From 0cf569549a3850f2d913a229faa687641ccc4413 Mon Sep 17 00:00:00 2001 From: Ryan Rasti Date: Sat, 11 Jul 2026 20:17:39 -0700 Subject: [PATCH] sqlite: typed function/operator surface, unified with the PG codegen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both pg and sqlite feed one emitter a typed schema of facts describing their function catalog. pg's facts are auto-generated on the fly from pg_catalog (as before — generated output is byte-identical). sqlite's facts are generated by running an LLM over the sqlite docs pages, committed as JSON, and sanity-checked against the real engine with deterministic quick-check-style tests. --- .gitignore | 1 + docs/ISSUES.md | 15 + package-lock.json | 41 + package.json | 5 +- src/builder/query.ts | 2 +- src/builder/sql.ts | 15 +- src/tables/generate.ts | 2 +- src/tables/sqlite.test.ts | 20 +- src/tables/sqlite.ts | 6 +- src/types/emission/common.ts | 39 + src/types/emission/emit.ts | 572 + src/types/emission/facts.ts | 67 + src/types/match.test.ts | 4 +- src/types/postgres/emit.ts | 279 + src/types/postgres/generate.ts | 615 - src/types/runtime.ts | 58 +- src/types/sql-value.ts | 27 +- src/types/sqlite/base.ts | 86 - src/types/sqlite/docs/.gitignore | 4 + src/types/sqlite/docs/VERSION | 3 + src/types/sqlite/docs/fetch.sh | 41 + src/types/sqlite/docs/index.ts | 195 + src/types/sqlite/docs/json1.json | 1122 ++ src/types/sqlite/docs/lang_aggfunc.json | 157 + src/types/sqlite/docs/lang_corefunc.json | 947 + src/types/sqlite/docs/lang_datefunc.json | 175 + src/types/sqlite/docs/lang_expr.json | 652 + src/types/sqlite/docs/lang_mathfunc.json | 866 + src/types/sqlite/docs/percentile.json | 133 + src/types/sqlite/emit.ts | 196 + src/types/sqlite/functions.json | 19931 ------------------- src/types/sqlite/generate.ts | 475 - src/types/sqlite/generated/any.ts | 173 + src/types/sqlite/generated/blob.ts | 438 +- src/types/sqlite/generated/bool.ts | 41 + src/types/sqlite/generated/integer.ts | 704 +- src/types/sqlite/generated/real.ts | 656 +- src/types/sqlite/generated/text.ts | 450 +- src/types/sqlite/index.ts | 8 +- src/types/sqlite/overrides/any.ts | 75 + src/types/sqlite/overrides/blob.ts | 14 + src/types/sqlite/overrides/bool.ts | 33 +- src/types/sqlite/overrides/integer.ts | 16 +- src/types/sqlite/overrides/real.ts | 8 +- src/types/sqlite/overrides/text.ts | 13 + src/types/sqlite/signatures.verify.test.ts | 432 + src/types/sqlite/smoke.test.ts | 162 +- vitest.config.ts | 1 + 48 files changed, 7258 insertions(+), 22717 deletions(-) create mode 100644 src/types/emission/common.ts create mode 100644 src/types/emission/emit.ts create mode 100644 src/types/emission/facts.ts create mode 100644 src/types/postgres/emit.ts delete mode 100644 src/types/postgres/generate.ts delete mode 100644 src/types/sqlite/base.ts create mode 100644 src/types/sqlite/docs/.gitignore create mode 100644 src/types/sqlite/docs/VERSION create mode 100755 src/types/sqlite/docs/fetch.sh create mode 100644 src/types/sqlite/docs/index.ts create mode 100644 src/types/sqlite/docs/json1.json create mode 100644 src/types/sqlite/docs/lang_aggfunc.json create mode 100644 src/types/sqlite/docs/lang_corefunc.json create mode 100644 src/types/sqlite/docs/lang_datefunc.json create mode 100644 src/types/sqlite/docs/lang_expr.json create mode 100644 src/types/sqlite/docs/lang_mathfunc.json create mode 100644 src/types/sqlite/docs/percentile.json create mode 100644 src/types/sqlite/emit.ts delete mode 100644 src/types/sqlite/functions.json delete mode 100644 src/types/sqlite/generate.ts create mode 100644 src/types/sqlite/generated/any.ts create mode 100644 src/types/sqlite/generated/bool.ts create mode 100644 src/types/sqlite/overrides/any.ts create mode 100644 src/types/sqlite/overrides/blob.ts create mode 100644 src/types/sqlite/overrides/text.ts create mode 100644 src/types/sqlite/signatures.verify.test.ts diff --git a/.gitignore b/.gitignore index 27fa999a..b47b2c7c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ site/public/demo.ts.static site/public/typegres.js site/public/typegres.d.ts packages/ +.claude/ diff --git a/docs/ISSUES.md b/docs/ISSUES.md index da8d1e02..a260605f 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -119,3 +119,18 @@ 14. ~~**`.live()` subscriptions**~~ — done (PR #72). Predicate extraction, reverse-index bus, MVCC-snapshot-aware re-iteration. + +## SQLite: results stringified, then re-parsed by deserializers + +better-sqlite3 already returns typed JS values (number, bigint, +string, Buffer, null), but `SqliteDriver.normalizeRow` stringifies +them all (`String(v)`, blobs → `\x`-hex) to satisfy `deserialize`'s +PG text-protocol contract (`raw: string`) — and the sqlite +deserializers immediately parse them back (`parseInt`, `parseFloat`, +hex → Uint8Array). A pointless double conversion, plus hazards: +int64 values > 2^53 stringify exactly but `parseInt` collapses them +to a lossy double, and blobs copy twice. + +Likely fix: widen the deserialize contract to `raw: unknown` (or +per-dialect raw types) so the sqlite driver can pass native values +through and deserializers just narrow/validate. diff --git a/package-lock.json b/package-lock.json index cae7f9fe..835c2f70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "acorn": "^8.16.0", "better-sqlite3": "^12.11.1", "eslint": "^10.2.1", + "fast-check": "^4.9.0", "pg": "^8.20.0", "prettier": "^3.8.3", "secure-json-parse": "^4.1.0", @@ -2162,6 +2163,29 @@ "node": ">=12.0.0" } }, + "node_modules/fast-check": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.9.0.tgz", + "integrity": "sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^8.0.0" + }, + "engines": { + "node": ">=12.17.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3235,6 +3259,23 @@ "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.2.tgz", + "integrity": "sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, "node_modules/quansync": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz", diff --git a/package.json b/package.json index c3dbf025..6a15a834 100644 --- a/package.json +++ b/package.json @@ -53,8 +53,8 @@ }, "scripts": { "build": "tsdown", - "codegen": "node --experimental-strip-types src/types/postgres/generate.ts && node --experimental-strip-types src/types/sqlite/generate.ts", - "codegen:check": "tmp=$(mktemp -d) && node --experimental-strip-types src/types/postgres/generate.ts --out-dir \"$tmp/pg\" && { diff -r \"$tmp/pg\" src/types/postgres/generated || { echo 'src/types/postgres/generated is stale — run `npm run codegen` and commit.' >&2; rm -rf \"$tmp\"; exit 1; }; } && node --experimental-strip-types src/types/sqlite/generate.ts --out-dir \"$tmp/sqlite\" && { diff -r \"$tmp/sqlite/generated\" src/types/sqlite/generated || { echo 'src/types/sqlite/generated is stale — run `npm run codegen` and commit.' >&2; rm -rf \"$tmp\"; exit 1; }; } && rm -rf \"$tmp\"", + "codegen": "node --experimental-strip-types src/types/postgres/emit.ts && node --experimental-strip-types src/types/sqlite/emit.ts", + "codegen:check": "tmp=$(mktemp -d) && node --experimental-strip-types src/types/postgres/emit.ts --out-dir \"$tmp/pg\" && { diff -r \"$tmp/pg\" src/types/postgres/generated || { echo 'src/types/postgres/generated is stale — run `npm run codegen` and commit.' >&2; rm -rf \"$tmp\"; exit 1; }; } && node --experimental-strip-types src/types/sqlite/emit.ts --out-dir \"$tmp/sqlite\" && { diff -r \"$tmp/sqlite/generated\" src/types/sqlite/generated || { echo 'src/types/sqlite/generated is stale — run `npm run codegen` and commit.' >&2; rm -rf \"$tmp\"; exit 1; }; } && rm -rf \"$tmp\"", "lint": "eslint src", "typecheck": "tsgo --noEmit", "format": "prettier --write src", @@ -76,6 +76,7 @@ "acorn": "^8.16.0", "better-sqlite3": "^12.11.1", "eslint": "^10.2.1", + "fast-check": "^4.9.0", "pg": "^8.20.0", "prettier": "^3.8.3", "secure-json-parse": "^4.1.0", diff --git a/src/builder/query.ts b/src/builder/query.ts index 6a0b5619..d55cb720 100644 --- a/src/builder/query.ts +++ b/src/builder/query.ts @@ -7,7 +7,7 @@ import { Connection } from "../database"; // dispatches per-dialect (Phase 2.1) these will be gated by ctx.dialect. import { Anyarray, Record } from "../types/postgres"; // Dialect-agnostic base for shape/predicate/instanceof checks — accepts -// PG's Any or SQLite's SqliteValue uniformly. +// PG's Any or SQLite's Any uniformly. import { SqlValue } from "../types/sql-value"; import { zBool, type Bool } from "../types/bool"; import { type TsTypeOf, type Nullable, type AggregateRow } from "../types/runtime"; diff --git a/src/builder/sql.ts b/src/builder/sql.ts index 6bedafee..01c77dc4 100644 --- a/src/builder/sql.ts +++ b/src/builder/sql.ts @@ -375,7 +375,20 @@ export const compile = (root: Sql, ctx: CompileContext): CompiledSql => { } else if (atom instanceof Ident) { out.push(quoteIdent(atom.name)); } else if (atom instanceof Param) { - values.push(atom.value); + // Raw-param semantics for sqlite are the JS ones: a JS number IS + // a double, so it binds as REAL (`sql\`${7} / ${2}\`` is 3.5, and + // typeof(${7}) is 'real'); BigInt binds as INTEGER. Typed + // positions are different — methods and table columns serialize + // through their class (CAST(? AS INTEGER/...)), so storage + // classes there follow the claim, not the binding. + // Booleans: SQLite has no boolean type — the convention is 0/1 + // INTEGER (BigInt so it binds as INTEGER, not REAL). A dialect + // fact, so it lives here in compilation rather than in any one + // driver. + const value = ctx.database.dialect === "sqlite" && typeof atom.value === "boolean" + ? (atom.value ? 1n : 0n) + : atom.value; + values.push(value); out.push(paramForDialect(ctx.database.dialect, values.length)); } else if (atom instanceof Alias) { const resolved = scope.resolve(atom); diff --git a/src/tables/generate.ts b/src/tables/generate.ts index 0e7a4fce..9d8ff541 100644 --- a/src/tables/generate.ts +++ b/src/tables/generate.ts @@ -22,7 +22,7 @@ import { pgNameToClassName } from "../types/postgres/introspect.ts"; export interface ColumnInfo { name: string; // Resolved TS class name for the type (e.g. "Int8", "Text", - // "Integer", "Bool", "SqliteValue"). The introspector resolves this + // "Integer", "Bool", "Any"). The introspector resolves this // at introspection time — shared codegen doesn't know how PG // typnames vs SQLite affinity resolve. className: string; diff --git a/src/tables/sqlite.test.ts b/src/tables/sqlite.test.ts index 397dd30a..263c8b9d 100644 --- a/src/tables/sqlite.test.ts +++ b/src/tables/sqlite.test.ts @@ -33,13 +33,13 @@ describe("affinityToClass — SQLite type affinity rules", () => { test("BOOLEAN → Bool (overlay before affinity)", () => { expect(affinityToClass("BOOLEAN")).toBe("Bool"); }); test("bool → Bool (case-insensitive)", () => { expect(affinityToClass("bool")).toBe("Bool"); }); - // NUMERIC affinity fall-through → SqliteValue (no narrow view). - test("DATE → SqliteValue (NUMERIC affinity, no domain type)", () => { - expect(affinityToClass("DATE")).toBe("SqliteValue"); + // NUMERIC affinity fall-through → Any (no narrow view). + test("DATE → Any (NUMERIC affinity, no domain type)", () => { + expect(affinityToClass("DATE")).toBe("Any"); }); - test("DATETIME → SqliteValue", () => { expect(affinityToClass("DATETIME")).toBe("SqliteValue"); }); - test("DECIMAL(10,2) → SqliteValue", () => { expect(affinityToClass("DECIMAL(10,2)")).toBe("SqliteValue"); }); - test("NUMERIC → SqliteValue", () => { expect(affinityToClass("NUMERIC")).toBe("SqliteValue"); }); + test("DATETIME → Any", () => { expect(affinityToClass("DATETIME")).toBe("Any"); }); + test("DECIMAL(10,2) → Any", () => { expect(affinityToClass("DECIMAL(10,2)")).toBe("Any"); }); + test("NUMERIC → Any", () => { expect(affinityToClass("NUMERIC")).toBe("Any"); }); // Classic SQLite affinity gotchas — we match SQLite's own behavior. test("FLOATING POINT → Integer (rule 1 catches 'POINT' → 'INT')", () => { @@ -48,8 +48,8 @@ describe("affinityToClass — SQLite type affinity rules", () => { test("CHARINT → Integer (rule 1 beats rule 2)", () => { expect(affinityToClass("CHARINT")).toBe("Integer"); }); - test("STRING → SqliteValue (no matching affinity rule)", () => { - expect(affinityToClass("STRING")).toBe("SqliteValue"); + test("STRING → Any (no matching affinity rule)", () => { + expect(affinityToClass("STRING")).toBe("Any"); }); }); @@ -109,7 +109,7 @@ describe("sqlite codegen e2e — DDL in, generated TypeScript out", () => { expect(files.get("dogs")).toMatchInlineSnapshot(` "import { db } from "../db"; import { expose, sql } from "typegres"; - import { Bool, Integer, SqliteValue, Text } from "typegres/sqlite"; + import { Any, Bool, Integer, Text } from "typegres/sqlite"; import { Teams } from "./teams"; export class Dogs extends db.Table("dogs") { @@ -119,7 +119,7 @@ describe("sqlite codegen e2e — DDL in, generated TypeScript out", () => { @expose() breed = (Text<0 | 1>).column(); @expose() team_id = (Integer<1>).column({ nonNull: true }); @expose() active = (Bool<1>).column({ nonNull: true, default: sql\`0\` }); - @expose() seen_at = (SqliteValue<0 | 1>).column(); + @expose() seen_at = (Any<0 | 1>).column(); // relations @expose() team() { return Teams.scope(Dogs.contextOf(this)).where(({ teams }) => teams.id.eq(this.team_id)).cardinality("one"); } // @generated-end diff --git a/src/tables/sqlite.ts b/src/tables/sqlite.ts index d169f57f..a3190719 100644 --- a/src/tables/sqlite.ts +++ b/src/tables/sqlite.ts @@ -45,7 +45,7 @@ interface IndexInfoRow { // "affinity" via ordered substring rules (§ 3.1 of the SQLite type // docs). We follow those rules 1:1 plus a small overlay for BOOLEAN // (a strong-enough convention to surface as our `Bool`). NUMERIC -// affinity resolves to `SqliteValue` — the base class with no narrow +// affinity resolves to `Any` — the base class with no narrow // method surface, which honestly reflects SQLite's dynamic typing. export const affinityToClass = (declaredType: string): string => { // BOOL/BOOLEAN overlay first — affinity rules would send this to @@ -63,10 +63,10 @@ export const affinityToClass = (declaredType: string): string => { if (/REAL|FLOA|DOUB/.test(t)) { return "Real"; } // NUMERIC fallback — DATE, DATETIME, TIMESTAMP, DECIMAL, MONEY, and - // custom names all land here. Bare SqliteValue: no narrow + // custom names all land here. Bare Any: no narrow // methods, `unknown` on hydration. User asserts intent at the call // site when treating it as a specific type. - return "SqliteValue"; + return "Any"; }; // `INTEGER PRIMARY KEY` (that exact declared type, not "INT") in a diff --git a/src/types/emission/common.ts b/src/types/emission/common.ts new file mode 100644 index 00000000..202b0b4a --- /dev/null +++ b/src/types/emission/common.ts @@ -0,0 +1,39 @@ +// Shared naming DATA for the unified emitter (../emission/emit.ts): +// operator-symbol aliases. Both dialects emit the same model — +// runtime.match dispatch under @expose.unchecked, camelCase function +// names, operator symbols as bracket methods plus readable aliases. + + +// Readable aliases for operator symbols (the catalogs don't provide +// nice names). Emitted as a second method next to the bracketed form: +// ['='](arg: M): Bool<...> // symbol form +// eq(arg: M): Bool<...> // alias +// Dialect-shared with PG's collision rule: the alias is SKIPPED when +// a real function already owns the name (pg: mod/pow exist as catalog +// functions; sqlite: mod()) — the function's signature is +// authoritative. +export const OPERATOR_ALIASES: { [op: string]: string } = { + "=": "eq", + "<>": "ne", + "<": "lt", + "<=": "lte", + ">": "gt", + ">=": "gte", + "+": "plus", + "-": "minus", + "*": "times", + "/": "divide", + "%": "mod", + "^": "pow", +}; + +// Unary operators are alias-only where the bracket form would collide +// (unary "-" vs binary minus); "~" keeps its bracket form too. +export const UNARY_OPERATOR_ALIASES: { [op: string]: string } = { + "-": "negate", + "~": "bitNot", +}; + + + + diff --git a/src/types/emission/emit.ts b/src/types/emission/emit.ts new file mode 100644 index 00000000..93460ea3 --- /dev/null +++ b/src/types/emission/emit.ts @@ -0,0 +1,572 @@ +// The unified emitter — signature facts in, generated TypeScript out. +// ONE method pipeline serves both dialects; there are no dialect +// branches in it. Every difference is driven by the facts or the type +// table: +// - variadic overloads ⇒ rest-args impl style + rest matchers +// (postgres facts never carry variadic — its output is unchanged +// by the facts, not by a flag); +// - doc strings ⇒ emitted doc lines (postgres facts carry none); +// - kind "unaryop" ⇒ unaryOpCall (sqlite-only kind); +// - isSrf/outColumns ⇒ Srf wrappers (postgres-only facts); +// - T-threading ⇒ fires only when the type table marks pseudotypes +// generic/element (sqlite's table marks none); +// - deterministic: false ⇒ not emitted (postgres pre-filters via +// provolatile, so the field is absent there). +// Class chrome (imports/statics/heritage), index/barrel files, and +// output paths are DATA the dialect entries pass in +// (postgres/emit.ts, sqlite/emit.ts). + +import * as fs from "node:fs"; +import * as path from "node:path"; +import camelcase from "camelcase"; +import { OPERATOR_ALIASES, UNARY_OPERATOR_ALIASES } from "./common.ts"; + +// --- facts --------------------------------------------------------------- +// The facts contract (zod schemas + inferred types) lives in +// ./facts.ts — re-exported here so dialect entries import one module. + +import type { EmitArg, EmitOverload, EmitFn } from "./facts.ts"; +export type { Nullability, EmitArg, EmitOverload, EmitFn } from "./facts.ts"; + +// --- type table ------------------------------------------------------------ + +export interface TypeEntry { + typname: string; + className: string; + primitiveTs?: string | undefined; // typeof-primitive accepted alongside instances + primitiveTsUnion?: string | undefined; // decl-side union when broader than one typeof (sqlite any/blob) + generic?: boolean | undefined; // container pseudotype: class takes + element?: boolean | undefined; // renders as T inside containers + // Same-return primitive-collision tie-break: when overloads collide + // on their primitive signature AND agree on the return type, the + // highest summed rank wins the primitive (sqlite: real outranks + // integer, so every number — fractional included — dispatches + // through the value-preserving REAL cast). Unset ⇒ the + // owner-overload rule decides. + losslessRank?: number | undefined; +} + +export interface EmitConfig { + typeTable: Map; + // Method names owned by hand-written base members (skipped here). + noMethod: Set; +} + +// --- naming ----------------------------------------------------------------- +// camelCase(sql) for functions; operators get the SQL symbol as a +// bracket method plus a readable alias (shared table + PG's collision +// rule against the host's real functions). Unary "-" is alias-only +// (bracket would collide with binary minus); keyword operators +// (IS NOT, ...) get camelCase aliases. + +const namesFor = (fn: EmitFn, hostFunctionNames: Set): string[] => { + if (fn.kind === "scalar" || fn.kind === "aggregate") { return [camelcase(fn.sql)]; } + const names: string[] = []; + if (!(fn.kind === "unaryop" && fn.sql === "-")) { names.push(`['${fn.sql}']`); } + const alias = fn.kind === "unaryop" + ? UNARY_OPERATOR_ALIASES[fn.sql] + : /[A-Za-z]/.test(fn.sql) ? camelcase(fn.sql) : OPERATOR_ALIASES[fn.sql]; + if (alias && !hostFunctionNames.has(alias)) { names.push(alias); } + return names; +}; + +// --- type resolution ---------------------------------------------------------- +// Containers (Anyarray etc.) need an element arg; bare +// references close directly with ; references to an element type +// from inside a container forward the owner's T. + +type ResolvedType = + | { kind: "T" } + | { kind: "unknown" } + | { kind: "simple"; className: string } + | { kind: "container"; className: string; elementArg: "T" | "types.Any" }; + +const resolveType = ( + typname: string | null, + owner: TypeEntry, + table: Map, +): ResolvedType => { + const t = typname === null ? undefined : table.get(typname); + if (!t) { return { kind: "unknown" }; } + if (t.generic) { + return { kind: "container", className: t.className, elementArg: owner.generic ? "T" : "types.Any" }; + } + if (owner.generic && t.element) { return { kind: "T" }; } + return { kind: "simple", className: t.className }; +}; + +const formatTypeWithNull = (r: ResolvedType, nullParam: string): string => { + switch (r.kind) { + case "T": return "T"; + case "unknown": return "unknown"; + case "simple": return `types.${r.className}<${nullParam}>`; + case "container": return `types.${r.className}<${r.elementArg}, ${nullParam}>`; + } +}; + +// --- the method pipeline -------------------------------------------------------- + +const paramsOf = (o: EmitOverload): EmitArg[] => o.args.slice(1); + +// Overloads hosted on a class: those whose receiver (first) arg carries its type. +const hostedOverloads = (fn: EmitFn, host: TypeEntry): EmitOverload[] => + fn.overloads.filter((o) => o.args[0]?.type === host.typname); + +export const emitMethods = (host: TypeEntry, allFns: EmitFn[], cfg: EmitConfig): string[] => { + const table = cfg.typeTable; + const lines: string[] = []; + + // Hosted definitions, and the host's real function names (backs the + // per-host operator-alias collision rule — pg's `mod`/`pow`). + const fns = allFns.filter((fn) => + fn.deterministic !== false && + hostedOverloads(fn, host).length > 0 && + !((fn.kind === "scalar" || fn.kind === "aggregate") && cfg.noMethod.has(camelcase(fn.sql)))); + const hostFunctionNames = new Set( + fns.filter((f) => f.kind === "scalar" || f.kind === "aggregate").map((f) => camelcase(f.sql)), + ); + + const primitiveTsFor = (typname: string | null): string => { + const t = typname === null ? undefined : table.get(typname); + return t?.primitiveTs ?? ""; + }; + const primitiveUnionFor = (typname: string | null): string | null => { + const t = typname === null ? undefined : table.get(typname); + return t?.primitiveTsUnion ?? t?.primitiveTs ?? null; + }; + + // Build generic param + TS type for a single arg. + const buildArgGeneric = (arg: EmitArg, i: number, allowPrimitive: boolean): string => { + const resolved = resolveType(arg.type, host, table); + const constraint = formatTypeWithNull(resolved, "any"); + const t = arg.type === null ? undefined : table.get(arg.type); + if (!t) { return `M${i} extends ${constraint}`; } + if (t.generic && host.generic) { + return `M${i} extends ${constraint}${allowPrimitive ? " | runtime.TsTypeOf[]" : ""}`; + } + if (t.element && host.generic) { + return `M${i} extends ${constraint}${allowPrimitive ? " | runtime.TsTypeOf" : ""}`; + } + if (t.generic || t.element) { + return `M${i} extends ${constraint}`; + } + return allowPrimitive + ? `M${i} extends ${constraint} | ${primitiveUnionFor(arg.type)}` + : `M${i} extends ${constraint}`; + }; + + // Does this overload's return follow the receiver? `arg0` binds the + // receiver as T so its class (and nullable form) survive the call. + const receiverGeneric = (o: EmitOverload): boolean => o.returns === "arg0"; + + // Return type string. `returns: "arg0"` binds the receiver as T + // (receiverGeneric above); everything else closes over the claimed + // type name with the overload's null semantics. + const buildRetType = (fn: EmitFn, o: EmitOverload): string => { + // `returns: "arg0"` (sqlite min/max/nullif): the return follows the + // RECEIVER's class — bind it as T and unwrap its nullable form, so + // `integerExpr.min()` stays Integer<0 | 1> instead of widening to Any. + if (receiverGeneric(o)) { + return `T extends { [meta]: { __nullable: infer U } } ? U : types.${host.className}<0 | 1>`; + } + const retName = o.returns; + const retBase = resolveType(retName, host, table); + const params = paramsOf(o); + if (fn.kind === "aggregate") { + return formatTypeWithNull(retBase, o.nullability === "never" ? "1" : "0 | 1"); + } + const included = (pos: number): boolean => !o.nullPositions || o.nullPositions.includes(pos); + const nullParts = [ + ...(included(0) ? ["N"] : []), + ...params + .map((a, i) => (included(o.args.indexOf(a)) ? `runtime.NullOf` : null)) + .filter((x): x is string => x !== null), + ]; + const nullUnion = nullParts.join(" | "); + if (o.nullability === "maybe_null") { + return formatTypeWithNull(retBase, `runtime.MaybeNull<${nullUnion}>`); + } + if (o.nullability === "never") { + return formatTypeWithNull(retBase, "1"); + } + if (o.nullability === "always" || o.nullability === "on_error") { + return formatTypeWithNull(retBase, "0 | 1"); + } + if (params.length === 0) { + return formatTypeWithNull(retBase, nullParts[0] ?? "N"); + } + return formatTypeWithNull(retBase, `runtime.StrictNull<${nullUnion}>`); + }; + + // Runtime expression for a case's return-type constructor. + // `arg0` is always the receiver's own class — runtime.pgType(this). + // On pg's abstract hosts, T-returns resolve via pgElement(this) and + // pseudotype self-returns via pgType(this). + const runtimeRetType = (o: EmitOverload): string => { + if (o.returns === "arg0") { return "runtime.pgType(this)"; } + const retName = o.returns; + const retBase = resolveType(retName, host, table); + if (retBase.kind === "T") { return "runtime.pgElement(this)"; } + if (retName === host.typname && (host.generic || host.element)) { return "runtime.pgType(this)"; } + const retT = retName === null ? undefined : table.get(retName); + return retT ? `types.${retT.className}` : `types.${host.className}`; + }; + + // Match cases for one overload: optional trailing args expand to one + // case per admissible arity; variadic tails use rest matchers. + const buildMatchCases = (fn: EmitFn, o: EmitOverload, allowPrimitive: boolean): string[] => { + const params = paramsOf(o); + const variadic = o.variadic === true; + const fixed = params; // variadic tail: first occurrence fixed, repeats via rest matcher + const matcher = (arg: EmitArg, rest: boolean): string => { + const t = arg.type === null ? undefined : table.get(arg.type); + if (!t) { return `{ type: types.Any${rest ? ", rest: true" : ""} }`; } + return `{ type: types.${t.className}${allowPrimitive ? ", allowPrimitive: true" : ""}${rest ? ", rest: true" : ""} }`; + }; + const requiredCount = fixed.filter((a) => !a.optional).length; + const cases: string[] = []; + for (let arity = requiredCount; arity <= fixed.length; arity++) { + const ms = fixed.slice(0, arity).map((a) => matcher(a, false)); + if (variadic && arity === fixed.length) { + ms.push(matcher(o.args[o.args.length - 1]!, true)); + } + cases.push(`[[${ms.join(", ")}], ${runtimeRetType(o)}]`); + if (variadic && arity === fixed.length) { break; } + } + return cases; + }; + + // Whether an overload's non-receiver args are all the host's own type. + const argsMatchOwner = (o: EmitOverload): boolean => + paramsOf(o).every((a) => a.type === host.typname); + + // An overload paired with the fn it came from. One emitted method can + // span several fns (sqlite's min/max: scalar + aggregate merge under + // one name), and kind/doc live on the fn. + interface FnOverload { fn: EmitFn; o: EmitOverload } + + // Decide allowPrimitive per overload within a group. Two types can + // share a TS primitive (pg: int8/inet are both `string`; sqlite: + // integer/real are both `number`), so letting both overloads accept + // it lets the wrong one win. Rule: + // - Group overloads by their TS-primitive signature across args. + // - Singleton: accepts primitives. + // - Colliding with EQUAL return types: the highest losslessRank + // sum wins (sqlite routes numbers to Real — no truncation). + // - Otherwise: only the owner-typed overload accepts primitives + // (its serialization cast makes the type claim true); the rest + // require explicit casts. + const computeAllowPrimitive = (pairs: FnOverload[]): Map => { + const primSig = (p: FnOverload): string => + paramsOf(p.o).map((a) => primitiveTsFor(a.type)).join("|"); + const rankOf = (p: FnOverload): number => + paramsOf(p.o).reduce((n, a) => n + (a.type ? (table.get(a.type)?.losslessRank ?? 0) : 0), 0); + + const byPrimSig = new Map(); + for (const p of pairs) { + const k = primSig(p); + if (!byPrimSig.has(k)) { byPrimSig.set(k, []); } + byPrimSig.get(k)!.push(p); + } + + const out = new Map(); + for (const colliding of byPrimSig.values()) { + if (colliding.length === 1) { + out.set(colliding[0]!.o, true); + continue; + } + const returns = new Set(colliding.map((p) => p.o.returns)); + const ranks = colliding.map(rankOf); + const maxRank = Math.max(...ranks); + if (returns.size === 1 && maxRank > Math.min(...ranks)) { + for (const [i, p] of colliding.entries()) { + out.set(p.o, ranks[i] === maxRank); + } + continue; + } + const ownerOverload = colliding.find((p) => argsMatchOwner(p.o)); + for (const p of colliding) { + out.set(p.o, p === ownerOverload); + } + } + return out; + }; + + // Signature header: name + generics + params. Optional args carry + // `?`; a variadic tail becomes a typed rest param. + const buildSig = (fn: EmitFn, o: EmitOverload, allowPrimitive: boolean, name: string): string => { + const params = paramsOf(o); + const variadic = o.variadic === true; + // A variadic tail repeats — its first occurrence is still a fixed + // param (required or optional per the fact); `...rest` covers the + // repeats. When the receiver itself is the tail (concat), no fixed + // params remain and the method is rest-only. + const fixed = params; + if (receiverGeneric(o)) { + // T binds the receiver (the return refers to it), so args don't + // need their own generics — plain unions suffice. + const paramSrc = fixed.map((a, i) => { + const resolved = formatTypeWithNull(resolveType(a.type, host, table), "any"); + const prim = allowPrimitive ? primitiveUnionFor(a.type) : null; + return `arg${i}${a.optional ? "?" : ""}: ${resolved}${prim ? ` | ${prim}` : ""}`; + }); + if (variadic) { + const last = o.args[o.args.length - 1]!; + const resolved = formatTypeWithNull(resolveType(last.type, host, table), "any"); + const prim = primitiveUnionFor(last.type); + paramSrc.push(`...rest: (${resolved}${prim ? ` | ${prim}` : ""})[]`); + } + return `${name}>(${["this: T", ...paramSrc].join(", ")})`; + } + const genericDecl = fixed.length > 0 + ? `<${fixed.map((a, i) => buildArgGeneric(a, i, allowPrimitive)).join(", ")}>` + : ""; + const paramSrc = fixed.map((a, i) => `arg${i}${a.optional ? "?" : ""}: M${i}`); + if (variadic) { + const last = o.args[o.args.length - 1]!; + const resolved = formatTypeWithNull(resolveType(last.type, host, table), "any"); + const prim = primitiveUnionFor(last.type); + paramSrc.push(`...rest: (${resolved}${prim ? ` | ${prim}` : ""})[]`); + } + return `${name}${genericDecl}(${paramSrc.join(", ")})`; + }; + + // Body: match dispatch + the caller for the fn's kind. + const buildBody = (fn: EmitFn, pairs: FnOverload[], allowMap: Map, inputExpr: string): string => { + const cases = pairs.flatMap((p) => buildMatchCases(p.fn, p.o, allowMap.get(p.o) ?? false)); + const matchCall = `runtime.match(${inputExpr}, [${cases.join(", ")}])`; + const callArgs = `[this, ...__rest]`; + const caller = fn.isSrf + ? `new runtime.Srf("${fn.sql}", ${callArgs}, [["${fn.sql}", __rt]])` + : fn.kind === "binop" + ? `runtime.opCall(runtime.sql\`${fn.sql}\`, [this, ...__rest] as [unknown, unknown], __rt)` + : fn.kind === "unaryop" + ? `runtime.unaryOpCall(runtime.sql\`${fn.sql}\`, this, __rt)` + : `runtime.funcCall("${fn.sql}", ${callArgs}, __rt)`; + return `const [__rt, ...__rest] = ${matchCall}; return ${caller} as any;`; + }; + + const wrapSrfRet = (fn: EmitFn, retType: string): string => + `runtime.Srf<{ ${fn.sql}: ${retType} }, "${fn.sql}">`; + + // --- emit every hosted definition --- + // Scalar/aggregate fns sharing a camelCase name (sqlite's min/max: + // the 2+-arg scalar and the aggregate form) merge into one method; + // everything else is its own unit. + const units: EmitFn[][] = []; + const funcUnits = new Map(); + for (const fn of fns) { + if (fn.kind === "scalar" || fn.kind === "aggregate") { + const key = camelcase(fn.sql); + const existing = funcUnits.get(key); + if (existing) { existing.push(fn); continue; } + const unit = [fn]; + funcUnits.set(key, unit); + units.push(unit); + } else { + units.push([fn]); + } + } + + for (const unit of units) { + const fn = unit[0]!; + const pairs: FnOverload[] = unit.flatMap((f) => + hostedOverloads(f, host).map((o) => ({ fn: f, o }))); + const o0 = pairs[0]!.o; + + // Multi-column SRF: shape comes from outColumns, match doesn't apply. + if (fn.isSrf && fn.outColumns && fn.outColumns.length > 0) { + const params = paramsOf(o0); + const argNames = params.map((_, i) => `arg${i}`); + const allArgs = argNames.length > 0 ? `this, ${argNames.join(", ")}` : "this"; + // Omitted optionals arrive as explicit undefined — filter before + // the Srf splices args into SQL. + const argsExpr = params.some((a) => a.optional) + ? `[${allArgs}].filter((a) => a !== undefined)` + : `[${allArgs}]`; + const colEntries = fn.outColumns.map((c) => { const t = table.get(c.type)!; return `${c.name}: types.${t.className}<1>`; }); + const colRuntime = fn.outColumns.map((c) => { const t = table.get(c.type)!; return `["${c.name}", types.${t.className}]`; }); + const sig = buildSig(fn, o0, true, camelcase(fn.sql)); + const ret = `runtime.Srf<{ ${colEntries.join("; ")} }, "${fn.sql}">`; + lines.push(...(fn.doc ? [` /** \`${fn.sql}\` — ${fn.doc} */`] : [])); + lines.push(` @expose.unchecked()`); + lines.push(` ${sig}: ${ret} { return new runtime.Srf("${fn.sql}", ${argsExpr}, [${colRuntime.join(", ")}]) as any; }`); + continue; + } + + const [primary, alias] = namesFor(fn, hostFunctionNames); + if (!primary) { continue; } + const docOf = (f: EmitFn): string[] => (f.doc ? [` /** \`${f.sql}\` — ${f.doc} */`] : []); + const doc = docOf(fn); + + const emitOne = (name: string): void => { + const allowMap = computeAllowPrimitive(pairs); + const variadicGroup = pairs.some((p) => p.o.variadic); + const hasOptionals = pairs.some((p) => paramsOf(p.o).some((a) => a.optional)); + // A receiver-generic decl types `this` as T; the impl then needs + // an explicit permissive `this` to stay overload-compatible. + const thisParam = pairs.some((p) => receiverGeneric(p.o)) ? "this: any, " : ""; + const wrapRet = fn.isSrf ? wrapSrfRet : (_: EmitFn, r: string) => r; + + if (pairs.length === 1 && !hasOptionals) { + // Single overload: typed one-liner (sig doubles as the impl). + const sig = buildSig(fn, o0, allowMap.get(o0) ?? true, name); + const retType = wrapRet(fn, buildRetType(fn, o0)); + const fixedCount = paramsOf(o0).length; // variadic tail's first occurrence is a fixed param + const inputExpr = `[${[ + ...Array.from({ length: fixedCount }, (_, i) => `arg${i}`), + ...(o0.variadic ? ["...rest"] : []), + ].join(", ")}]`; + lines.push(...doc); + lines.push(` @expose.unchecked()`); + lines.push(` ${sig}: ${retType} { ${buildBody(fn, pairs, allowMap, inputExpr)} }`); + return; + } + + // Multiple overloads (or optionals): TS overload signatures over + // one typed-as-any implementation dispatching via match. The + // decorator goes on the implementation only. + for (const p of pairs) { + const sig = buildSig(p.fn, p.o, allowMap.get(p.o) ?? false, name); + const retType = (p.fn.isSrf ? wrapSrfRet : (_: EmitFn, r: string) => r)(p.fn, buildRetType(p.fn, p.o)); + lines.push(...docOf(p.fn)); + lines.push(` ${sig}: ${retType};`); + } + if (variadicGroup) { + lines.push(` @expose.unchecked()`); + lines.push(` ${name}(${thisParam}...args: unknown[]): any { ${buildBody(fn, pairs, allowMap, "args")} }`); + return; + } + // Impl sig covers all arities — required up to min, optional up to max. + const requiredArities = pairs.map((p) => paramsOf(p.o).filter((a) => !a.optional).length); + const arities = pairs.map((p) => paramsOf(p.o).length); + const minArity = Math.min(...requiredArities); + const maxArity = Math.max(...arities); + const implParams = Array.from({ length: maxArity }, (_, i) => + `arg${i}${i >= minArity ? "?" : ""}: unknown`, + ).join(", "); + const inputExpr = `[${Array.from({ length: maxArity }, (_, i) => `arg${i}`).join(", ")}]`; + lines.push(` @expose.unchecked()`); + lines.push(` ${name}(${thisParam}${implParams}): any { ${buildBody(fn, pairs, allowMap, inputExpr)} }`); + }; + + emitOne(primary); + if (alias) { emitOne(alias); } + } + + return lines; +}; + +// --- class files ------------------------------------------------------------- +// Chrome (header/imports/class decl/statics) is dialect data around +// the unified method pipeline. The pieces below are structurally +// identical across dialects; the entries compose them with their own +// heritage, brands, and doc lines. + +export interface ClassChrome { + prologue: string; // everything before the methods + epilogue: string; // closing brace etc. +} + +// The import block every generated class file shares. `parentImport` +// is the dialect's parent-class import line — a DIRECT import, not +// `types.Parent`: class `extends` clauses evaluate at module-load +// time, and the barrel may not have finished loading when this file +// runs. Method bodies use `types.X` freely — those are lazy, so load +// order doesn't matter. expose: @expose.unchecked exposes every +// codegen'd method to exoeval-bound code without arg validation +// (runtime.match already validates internally). +export const chromeImportLines = (parentImport: string): string[] => [ + 'import * as runtime from "../../runtime";', + 'import { meta } from "../../sql-value";', + 'import { expose } from "../../../exoeval/tool";', + parentImport, + 'import * as types from "../index";', + "", +]; + +// The [meta] declare block — the narrow self-typing every concrete +// class carries. `clsRef` is the bare class name, or `types.Cls` when +// a hand-written override is the barrel export (the generated class +// then points at the override so nullability transforms and +// runtime.pgType land on the full class). +export const metaDeclareLines = (clsRef: string): string[] => [ + ` declare [meta]: {`, + ` __class: typeof ${clsRef};`, + ` __raw: runtime.Sql;`, + ` __nullability: N;`, + ` __nullable: ${clsRef}<0 | 1>;`, + ` __nonNullable: ${clsRef}<1>;`, + ` __aggregate: ${clsRef};`, + ` __any: ${clsRef};`, + ` };`, +]; + +// __typname (the CAST/render target) + __typnameText (dispatch and +// error-message key). `override` when an ancestor already defines +// them (sqlite's views extend Any, which does; pg's concrete classes +// are first definers). +export const typnameStaticLines = (sqlLiteral: string, typnameText: string, override: boolean): string[] => { + const kw = override ? "override " : ""; + return [ + ` static ${kw}__typname = runtime.sql\`${sqlLiteral}\`;`, + ` static ${kw}__typnameText = "${typnameText}";`, + ]; +}; + +// Hand-written override files (overrides/.ts) shadow their +// generated class in the barrel and in parent imports. +export const scanOverrideNames = (overridesDir: string): Set => { + const overrides = new Set(); + if (fs.existsSync(overridesDir)) { + for (const file of fs.readdirSync(overridesDir)) { + if (file.endsWith(".ts")) { + overrides.add(file.replace(".ts", "")); + } + } + } + return overrides; +}; + +// One barrel line per class: the override when one exists, else the +// generated file. +const barrelExportLine = (t: TypeEntry, overridden: boolean): string => + `export { ${t.className} } from "./${overridden ? "overrides" : "generated"}/${t.typname}";`; + +export const emitClassFile = (host: TypeEntry, chrome: ClassChrome, fns: EmitFn[], cfg: EmitConfig): string => + [chrome.prologue, ...emitMethods(host, fns, cfg), chrome.epilogue].join("\n"); + +// --- tree writer --------------------------------------------------------------- +// The output step both dialects share: a clean generated/ dir of class +// files, then the barrel's marker block. Text outside [generated-start]/[generated-end] +// is hand-written and preserved. + +export const writeGeneratedTree = (opts: { + generatedDir: string; + barrelPath: string; + types: TypeEntry[]; + facts: EmitFn[]; + cfg: EmitConfig; + chromeFor: (t: TypeEntry) => ClassChrome; + overrides: Set; +}): void => { + fs.rmSync(opts.generatedDir, { recursive: true, force: true }); + fs.mkdirSync(opts.generatedDir, { recursive: true }); + for (const t of opts.types) { + fs.writeFileSync( + path.join(opts.generatedDir, `${t.typname}.ts`), + emitClassFile(t, opts.chromeFor(t), opts.facts, opts.cfg), + ); + } + const src = fs.readFileSync(opts.barrelPath, "utf8"); + const start = src.indexOf("// [generated-start]"); + const end = src.indexOf("// [generated-end]"); + if (start < 0 || end < 0) { + throw new Error(`${opts.barrelPath}: missing [generated-start]/[generated-end] markers`); + } + const exports = [...opts.types] + .sort((a, b) => a.typname.localeCompare(b.typname)) + .map((t) => barrelExportLine(t, opts.overrides.has(t.typname))); + const block = ["// [generated-start]", ...exports].join("\n") + "\n"; + fs.writeFileSync(opts.barrelPath, src.slice(0, start) + block + src.slice(end)); +}; diff --git a/src/types/emission/facts.ts b/src/types/emission/facts.ts new file mode 100644 index 00000000..d3d0feea --- /dev/null +++ b/src/types/emission/facts.ts @@ -0,0 +1,67 @@ +// THE facts schema — the single signature contract the unified +// emitter (./emit.ts) consumes. Both dialects produce instances of +// it: postgres builds them in memory from the catalog +// (postgres/emit.ts produceFacts — mechanical, nothing to validate); +// sqlite commits them as docs/*.json and zod-validates them on load +// (LLM-extracted, so validation is load-bearing; see +// sqlite/docs/index.ts for the sqlite-specific refinements layered on +// top: storage-class/hint vocabularies, required docs). +// +// The TS types are INFERRED from these schemas, so the emitter's +// contract and the validator cannot drift. +import z from "zod"; + +export const NullabilitySchema = z.enum([ + "propagates", // NULL in any arg → NULL out; non-null in → non-null out + "never", // non-null even for NULL inputs (hex(NULL) = '') + "always", // may be NULL on valid non-null input (aggregate over ∅) + "on_error", // NULL is the error signal (date parse failure, bad path) + "maybe_null", // may be NULL on key-miss (pg's ->/->> family) +]); + +export const EmitArgSchema = z.object({ + type: z.string().nullable(), // type-table name; null = unknown (pg catalog gaps) + hint: z.string().optional(), // verifier sample-domain hint (sqlite; inert in emission) + optional: z.boolean().optional(), // trailing optional parameter +}); + +export const EmitOverloadSchema = z.object({ + // In the SQL call's EXACT documented order; args[0] is the method + // receiver (100% call-order fidelity — the emitted SQL is always + // fn(this, ...rest)). sqlite functions that lead with a pattern or + // format string host there (pattern.like(x), format.strftime(t)); + // like/glob's string-first direction stays available as the infix + // LIKE/GLOB operators. + args: z.array(EmitArgSchema), + variadic: z.boolean().optional(), // last arg repeats 0+ more times + returns: z.string().nullable(), // type name, "arg0", or null (unknown / SRF row) + nullability: NullabilitySchema, + // Positions where NULL injection is part of the domain — for + // "propagates", only these positions propagate (concat_ws skips + // NULL values); for "never", only these positions tolerate NULL at + // all (json_object labels may not be NULL). Omitted ⇒ every + // position. + nullPositions: z.array(z.number()).optional(), +}); + +export const EmitFnSchema = z.object({ + sql: z.string(), // SQL spelling (function name or operator symbol) + kind: z.enum(["scalar", "aggregate", "binop", "unaryop"]), + doc: z.string().optional(), // one-sentence summary (sqlite pages; pg carries none) + // Whether the function is deterministic (same inputs ⇒ same output). + // Non-deterministic functions are NOT emitted to the typed surface + // (postgres pre-filters via provolatile='i', so the field is absent + // there; sqlite's claim is cross-checked against the engine's + // SQLITE_DETERMINISTIC flag by the verifier). + deterministic: z.boolean().optional(), + // Set-returning (table-valued) function: emitted as an Srf with the + // fixed row shape in outColumns instead of a scalar return. + isSrf: z.boolean().optional(), + outColumns: z.array(z.object({ name: z.string(), type: z.string() })).optional(), + overloads: z.array(EmitOverloadSchema).min(1), +}); + +export type Nullability = z.infer; +export type EmitArg = z.infer; +export type EmitOverload = z.infer; +export type EmitFn = z.infer; diff --git a/src/types/match.test.ts b/src/types/match.test.ts index 8215c78c..2aad6638 100644 --- a/src/types/match.test.ts +++ b/src/types/match.test.ts @@ -79,7 +79,7 @@ test("serialize: instance passes through", () => { }); test("serialize: wrong type throws", () => { - expect(() => Int4.serialize("hello")).toThrow("int4.serialize: expected a int4 instance or number primitive"); + expect(() => Int4.serialize("hello")).toThrow("int4.serialize: expected a int4 instance or an accepted primitive"); }); test("serialize: null throws", () => { @@ -92,5 +92,5 @@ test("serialize: string for Int8 passes", () => { }); test("serialize: number for Int8 throws", () => { - expect(() => Int8.serialize(42)).toThrow("int8.serialize: expected a int8 instance or string primitive"); + expect(() => Int8.serialize(42)).toThrow("int8.serialize: expected a int8 instance or an accepted primitive"); }); diff --git a/src/types/postgres/emit.ts b/src/types/postgres/emit.ts new file mode 100644 index 00000000..c3e13d94 --- /dev/null +++ b/src/types/postgres/emit.ts @@ -0,0 +1,279 @@ +import pg from "pg"; +import camelcase from "camelcase"; +import { OPERATOR_ALIASES } from "../emission/common.ts"; +import { + writeGeneratedTree, + chromeImportLines, + metaDeclareLines, + typnameStaticLines, + scanOverrideNames, + type EmitFn, + type TypeEntry, + type Nullability, + type ClassChrome, +} from "../emission/emit.ts"; +import * as path from "node:path"; +import { pathToFileURL } from "node:url"; +import { requireDatabaseUrl } from "../../pg.ts"; +import { + introspect, + groupByFirstArg, + type PgType, + type PgFunc, +} from "./introspect.ts"; + +// `--out-dir ` lets codegen:check write to a temp dir instead of +// clobbering the committed sources. +const outDirFlag = process.argv.indexOf("--out-dir"); +const GENERATED_DIR = outDirFlag >= 0 + ? path.resolve(process.argv[outDirFlag + 1]!) + : path.resolve(import.meta.dirname, "generated"); +const OVERRIDES_DIR = path.resolve(import.meta.dirname, "overrides"); +const TYPES_INDEX = path.resolve(import.meta.dirname, "index.ts"); + +// TS-primitive `typeof` accepted by each pg type via allowPrimitive. The +// concrete override files (overrides/int4.ts, overrides/bool.ts, ...) +// set `static primitiveTs` to the same value — this map only exists +// so codegen can build `M0 extends Cls | number` in method arg +// constraints and disambiguate primitive-sig-colliding overloads. Add +// an entry here when adding a matching overrides/.ts; everything +// unlisted defaults to "string" (identity). +const primitiveTsFor = (typname: string): string => { + switch (typname) { + case "bool": return "boolean"; + case "int2": + case "int4": + case "float4": + case "float8": + case "oid": return "number"; + default: return "string"; + } +}; + +// Types that get a generic > parameter +const GENERIC_TYPES = new Set([ + "anyarray", + "anycompatiblearray", + "anyrange", + "anycompatiblerange", + "anymultirange", + "anycompatiblemultirange", +]); + +// Types that become T when referenced from other classes +// (they represent "the element type" in polymorphic signatures) +const ELEMENT_TYPES = new Set([ + "anyelement", + "anynonarray", + "anycompatible", + "anycompatiblenonarray", + "anyenum", +]); + +const EXTENDS_MAP: { [key: string]: string } = { + anycompatible: "Any", + anyelement: "Anycompatible", + anycompatiblenonarray: "Anyelement", + anynonarray: "Anycompatiblenonarray", + anyenum: "Anynonarray", + anycompatiblearray: "Anyelement", + anyarray: "Anycompatiblearray", + anycompatiblerange: "Anyelement", + anyrange: "Anycompatiblerange", + anycompatiblemultirange: "Anyelement", + anymultirange: "Anycompatiblemultirange", +}; + +// Operators that can return null from non-null inputs (e.g. JSON key not +// found). Includes the pg function names for the same ops, since those +// are emitted when the operator doesn't have a readable alias in +// OPERATOR_ALIASES (see introspect.ts oprcode filter). +const MAYBE_NULL_OPS = new Set([ + "->", "->>", "#>", "#>>", + "jsonb_object_field", "jsonb_object_field_text", + "jsonb_extract_path", "jsonb_extract_path_text", + "json_object_field", "json_object_field_text", + "json_extract_path", "json_extract_path_text", +]); + +// Readable aliases for operators pg doesn't give a nice function name +// (comparison + arithmetic). Emitted as a second method next to the +// bracketed form: +// ['='](arg: M): Bool<...> // already emitted +// eq(arg: M): Bool<...> // alias +// +// introspect.ts hides pg's oprcode implementations only for operators +// in this map — so `int4eq`, `int42pl`, etc. don't clutter the types, +// but pg's readable function names for unaliased operators (`texticlike` +// for ~~*, `jsonb_object_field` for ->, `array_prepend` for ||, ...) +// stay available alongside the bracketed form. + +// --- Facts ------------------------------------------------------------------ +// Catalog-independent signature facts — the instance the unified +// emitter consumes. Generated on the fly from the catalog (never +// committed): the catalog IS the source of truth, so unlike sqlite's +// LLM-extracted JSONs there is nothing to review or verify. Types are +// typnames (strings), not OIDs; args INCLUDE the receiver position +// (the emitter places by the FIRST arg's type — the same rule as +// sqlite). Order: per-host catalog buckets, functions before +// operators, so per-host emission order is stable. +const produceFacts = (typeMap: Map, pgFuncs: PgFunc[]): EmitFn[] => { + const nameOf = (oid: number): string | null => typeMap.get(oid)?.typname ?? null; + const grouped = groupByFirstArg(pgFuncs); + const out: EmitFn[] = []; + for (const [oid, funcs] of grouped) { + const host = typeMap.get(oid); + if (!host) { continue; } + // Group real pg overloads (same name) into one fact; skip the + // subtype-incompatible overload sets that each subtype defines + // for itself. + const funcGroups = new Map(); + const operatorGroups = new Map(); + for (const f of funcs) { + if (host.typname === "anyelement" && f.isOperator && f.name === "<@") { continue; } // overloaded: array<@array, range<@range, elem<@multirange + if (host.typname === "anycompatible" && f.isOperator && f.name === "||") { continue; } // overloaded: text||text, array||array, bytea||bytea, etc. + if (host.typname === "anynonarray" && f.isOperator && f.name === "||") { continue; } // overloaded: text||anynonarray, but concrete types define their own || + if (host.typname === "anycompatible" && !f.isOperator && f.name === "width_bucket") { continue; } // overloaded with different arities by float8, numeric + const groups = f.isOperator ? operatorGroups : funcGroups; + const key = f.isOperator ? f.name : camelcase(f.name); + if (!groups.has(key)) { groups.set(key, []); } + groups.get(key)!.push(f); + } + const toFact = (group: PgFunc[]): EmitFn => { + const f0 = group[0]!; + const nullability = (f: PgFunc): Nullability => { + if (f.isAggregate) { return f.name === "count" ? "never" : "always"; } + if (MAYBE_NULL_OPS.has(f.name)) { return "maybe_null"; } + return f.isStrict ? "propagates" : "never"; + }; + return { + sql: f0.name, + kind: f0.isOperator ? "binop" : f0.isAggregate ? "aggregate" : "scalar", + isSrf: f0.isSrf ?? false, + outColumns: f0.outColumns?.map((c) => ({ name: c.name, type: typeMap.get(c.typeOid)!.typname })), + overloads: group.map((f) => ({ + args: f.argTypes.map((argOid) => ({ type: nameOf(argOid) })), + returns: nameOf(f.returnType), + nullability: nullability(f), + })), + }; + }; + out.push( + ...[...funcGroups.values()].map(toFact), + ...[...operatorGroups.values()].map(toFact), + ); + } + return out; +}; + +const scanOverrides = (): Set => scanOverrideNames(OVERRIDES_DIR); + +// --- class chrome ------------------------------------------------------------ +// The pg class shell around the unified method pipeline: imports, +// heritage (pseudotype hierarchy), meta declare + statics for +// concrete types. +const pgChrome = ( + pgType: TypeEntry, + nameTable: Map, + overrideNames: Set, +): ClassChrome => { + const isGeneric = GENERIC_TYPES.has(pgType.typname); + const extendsClass = EXTENDS_MAP[pgType.typname]; + const parentIsContainer = extendsClass !== undefined + && [...GENERIC_TYPES].some((n) => nameTable.get(n)?.className === extendsClass); + + const parentTypname = pgType.typname === "any" + ? undefined + : extendsClass + ? Object.keys(EXTENDS_MAP).find((k) => nameTable.get(k)?.className === extendsClass) + ?? "any" + : "anynonarray"; + const parentImport = pgType.typname === "any" + ? 'import { SqlValue } from "../../sql-value";' + : `import { ${nameTable.get(parentTypname!)!.className} } from "../${ + overrideNames.has(parentTypname!) ? "overrides" : "generated"}/${parentTypname}";`; + + const lines: string[] = []; + lines.push("// Auto-generated — do not edit"); + lines.push(...chromeImportLines(parentImport)); + + // Explicit `in out N` variance annotation skips TS's structural + // variance inference across 77 mutually-referencing classes. + let classDecl = `export class ${pgType.className}`; + if (isGeneric) { + classDecl += `, in out N extends number>`; + } else { + classDecl += ``; + } + if (extendsClass) { + // Parent takes T only if it's a container itself. + classDecl += parentIsContainer + ? ` extends ${extendsClass}` + : ` extends ${extendsClass}`; + } else if (pgType.typname === "any") { + classDecl += ` extends SqlValue`; + } else { + classDecl += ` extends Anynonarray`; + } + classDecl += " {"; + lines.push(classDecl); + + if (pgType.typname === "any") { + // Handled by override — no-op here + } else if (!EXTENDS_MAP[pgType.typname]) { + // Concrete type — narrow [meta] + statics; `declare deserialize` + // return-type marker unless a hand-written override provides it. + const cls = pgType.className; + const ref = overrideNames.has(pgType.typname) ? `types.${cls}` : cls; + lines.push(...metaDeclareLines(ref)); + lines.push(...typnameStaticLines(pgType.typname, pgType.typname, false)); + if (!overrideNames.has(pgType.typname)) { + lines.push(` declare deserialize: (raw: string) => ${primitiveTsFor(pgType.typname)};`); + } + } else { + // any* hierarchy type — inherits [meta] from parent, no re-declaration needed + } + + return { prologue: lines.join("\n"), epilogue: "}\n" }; +}; + +export const generate = async () => { + const db = new pg.Pool({ connectionString: requireDatabaseUrl() }); + + try { + const { typeMap, pgFuncs } = await introspect(db, Object.keys(OPERATOR_ALIASES)); + const types: TypeEntry[] = [...typeMap.values()].map((t) => ({ + typname: t.typname, + className: t.className, + primitiveTs: primitiveTsFor(t.typname), + generic: GENERIC_TYPES.has(t.typname), + element: ELEMENT_TYPES.has(t.typname), + })); + const nameTable = new Map(types.map((t) => [t.typname, t])); + const overrideNames = scanOverrides(); + + writeGeneratedTree({ + generatedDir: GENERATED_DIR, + barrelPath: TYPES_INDEX, + types, + // Facts instance — catalog-independent (typnames, not OIDs), + // generated on the fly. This is what the unified emitter + // consumes; sqlite's equivalent is its committed docs/*.json. + facts: produceFacts(typeMap, pgFuncs), + cfg: { typeTable: nameTable, noMethod: new Set() }, + chromeFor: (host) => pgChrome(host, nameTable, overrideNames), + overrides: overrideNames, + }); + console.log(`Generated ${types.length} types in ${GENERATED_DIR}`); + } finally { + await db.end(); + } +}; + +// Run only when executed directly, not when imported. +if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { + generate().catch((err) => { + console.error(err); + process.exit(1); + }); +} diff --git a/src/types/postgres/generate.ts b/src/types/postgres/generate.ts deleted file mode 100644 index ecce0eef..00000000 --- a/src/types/postgres/generate.ts +++ /dev/null @@ -1,615 +0,0 @@ -import pg from "pg"; -import camelcase from "camelcase"; -import * as fs from "node:fs"; -import * as path from "node:path"; -import { pathToFileURL } from "node:url"; -import { requireDatabaseUrl } from "../../pg.ts"; -import { - introspect, - groupByFirstArg, - pgNameToClassName, - type PgType, - type PgFunc, -} from "./introspect.ts"; - -// `--out-dir ` lets codegen:check write to a temp dir instead of -// clobbering the committed sources. -const outDirFlag = process.argv.indexOf("--out-dir"); -const GENERATED_DIR = outDirFlag >= 0 - ? path.resolve(process.argv[outDirFlag + 1]!) - : path.resolve(import.meta.dirname, "generated"); -const OVERRIDES_DIR = path.resolve(import.meta.dirname, "overrides"); -const TYPES_INDEX = path.resolve(import.meta.dirname, "index.ts"); - -// TS-primitive `typeof` accepted by each pg type via allowPrimitive. The -// concrete override files (overrides/int4.ts, overrides/bool.ts, ...) -// set `static primitiveTs` to the same value — this map only exists -// so codegen can build `M0 extends Cls | number` in method arg -// constraints and disambiguate primitive-sig-colliding overloads. Add -// an entry here when adding a matching overrides/.ts; everything -// unlisted defaults to "string" (identity). -const primitiveTsFor = (typname: string): string => { - switch (typname) { - case "bool": return "boolean"; - case "int2": - case "int4": - case "float4": - case "float8": - case "oid": return "number"; - default: return "string"; - } -}; - -// Types that get a generic > parameter -const GENERIC_TYPES = new Set([ - "anyarray", - "anycompatiblearray", - "anyrange", - "anycompatiblerange", - "anymultirange", - "anycompatiblemultirange", -]); - -// Types that become T when referenced from other classes -// (they represent "the element type" in polymorphic signatures) -const ELEMENT_TYPES = new Set([ - "anyelement", - "anynonarray", - "anycompatible", - "anycompatiblenonarray", - "anyenum", -]); - -// Operators that can return null from non-null inputs (e.g. JSON key not -// found). Includes the pg function names for the same ops, since those -// are emitted when the operator doesn't have a readable alias in -// OPERATOR_ALIASES (see introspect.ts oprcode filter). -const MAYBE_NULL_OPS = new Set([ - "->", "->>", "#>", "#>>", - "jsonb_object_field", "jsonb_object_field_text", - "jsonb_extract_path", "jsonb_extract_path_text", - "json_object_field", "json_object_field_text", - "json_extract_path", "json_extract_path_text", -]); - -// Readable aliases for operators pg doesn't give a nice function name -// (comparison + arithmetic). Emitted as a second method next to the -// bracketed form: -// ['='](arg: M): Bool<...> // already emitted -// eq(arg: M): Bool<...> // alias -// -// introspect.ts hides pg's oprcode implementations only for operators -// in this map — so `int4eq`, `int42pl`, etc. don't clutter the types, -// but pg's readable function names for unaliased operators (`texticlike` -// for ~~*, `jsonb_object_field` for ->, `array_prepend` for ||, ...) -// stay available alongside the bracketed form. -const OPERATOR_ALIASES: { [op: string]: string } = { - "=": "eq", - "<>": "ne", - "<": "lt", - "<=": "lte", - ">": "gt", - ">=": "gte", - "+": "plus", - "-": "minus", - "*": "times", - "/": "divide", - "%": "mod", - "^": "pow", -}; - -// Inheritance hierarchy: -// Any -// └─ Anycompatible -// └─ Anyelement -// ├─ Anycompatiblenonarray -// │ └─ Anynonarray -// │ ├─ Anyenum -// │ ├─ Int4 (T = Int4) -// │ ├─ Text (T = Text) -// │ └─ ... all concrete types -// ├─ Anycompatiblearray -// │ └─ Anyarray -// ├─ Anycompatiblerange -// │ └─ Anyrange -// └─ Anycompatiblemultirange -// └─ Anymultirange -const EXTENDS_MAP: { [key: string]: string } = { - anycompatible: "Any", - anyelement: "Anycompatible", - anycompatiblenonarray: "Anyelement", - anynonarray: "Anycompatiblenonarray", - anyenum: "Anynonarray", - anycompatiblearray: "Anyelement", - anyarray: "Anycompatiblearray", - anycompatiblerange: "Anyelement", - anyrange: "Anycompatiblerange", - anycompatiblemultirange: "Anyelement", - anymultirange: "Anycompatiblemultirange", -}; - - -// Resolution of a pg-type OID to its TS representation, before the -// nullability param is filled in. Containers (Anyarray etc.) need an -// element arg; bare references close directly with ; references to an -// element type from inside a container forward the owner's T. -type ResolvedType = - | { kind: "T" } - | { kind: "unknown" } - | { kind: "simple"; className: string } - | { kind: "container"; className: string; elementArg: "T" | "types.Any" }; - -const resolveBaseTypeName = ( - oid: number, - ownerType: PgType, - typeMap: Map, -): ResolvedType => { - const t = typeMap.get(oid); - if (!t) { return { kind: "unknown" }; } - - const ownerIsContainer = GENERIC_TYPES.has(ownerType.typname); - - if (GENERIC_TYPES.has(t.typname)) { - return { - kind: "container", - className: t.className, - elementArg: ownerIsContainer ? "T" : "types.Any", - }; - } - - // Inside a container, references to element-type classes forward the - // owner's T — that's the semantic "the element type" slot. - if (ownerIsContainer && ELEMENT_TYPES.has(t.typname)) { - return { kind: "T" }; - } - - return { kind: "simple", className: t.className }; -}; - -const formatTypeWithNull = (r: ResolvedType, nullParam: string): string => { - switch (r.kind) { - case "T": return "T"; - case "unknown": return "unknown"; - case "simple": return `types.${r.className}<${nullParam}>`; - case "container": return `types.${r.className}<${r.elementArg}, ${nullParam}>`; - } -}; - -const generateTypeFile = ( - pgType: PgType, - funcs: PgFunc[], - typeMap: Map, - overrideNames: Set, -): string => { - const isGeneric = GENERIC_TYPES.has(pgType.typname); - const isElement = ELEMENT_TYPES.has(pgType.typname); - const extendsClass = EXTENDS_MAP[pgType.typname]; - // Only container types carry a T param. Element types (anyelement, - // anynonarray, anycompatible, anycompatiblenonarray, anyenum) dropped T to - // break the self-referential variance loop: Int4 used to extend - // Anynonarray, N>, which forced TS to relate Int4 to itself to - // compute variance. Containers still keep T (they genuinely need the - // element type in their method signatures). - const needsGenericT = isGeneric; - const parentIsContainer = extendsClass !== undefined - && [...GENERIC_TYPES].some((n) => pgNameToClassName(n) === extendsClass); - - // Group both functions and operators by name so real pg overloads (e.g. - // substring(bit, int4) and substring(bit, int4, int4)) become a single - // method with multiple TS overload signatures. - const funcGroups = new Map(); - const operatorGroups = new Map(); - - for (const f of funcs) { - // Skip operators/functions overloaded incompatibly by subtypes — each subtype defines its own version - if (pgType.typname === "anyelement" && f.isOperator && f.name === "<@") { continue; } // overloaded: array<@array, range<@range, elem<@multirange - if (pgType.typname === "anycompatible" && f.isOperator && f.name === "||") { continue; } // overloaded: text||text, array||array, bytea||bytea, etc. - if (pgType.typname === "anynonarray" && f.isOperator && f.name === "||") { continue; } // overloaded: text||anynonarray, but concrete types define their own || - if (pgType.typname === "anycompatible" && !f.isOperator && f.name === "width_bucket") { continue; } // overloaded with different arities by float8, numeric - - const groups = f.isOperator ? operatorGroups : funcGroups; - const key = f.isOperator ? f.name : camelcase(f.name); - if (!groups.has(key)) { groups.set(key, []); } - groups.get(key)!.push(f); - } - - const lines: string[] = []; - lines.push("// Auto-generated — do not edit"); - lines.push('import * as runtime from "../../runtime";'); - lines.push('import { meta } from "../../sql-value";'); - // @expose.unchecked exposes every codegen'd method to exoeval-bound code - // without arg validation (typegres's runtime overload dispatcher already - // validates internally). One import here, prepended on every method. - lines.push('import { expose } from "../../../exoeval/tool";'); - - // Parent class needs a direct import, not `types.Parent`: class `extends` - // clauses evaluate at module-load time, and the barrel may not have finished - // loading when this file runs. Method bodies use `types.X` freely — those - // are lazy, so load order doesn't matter. - // - // The root `any` type extends the shared dialect-agnostic `SqlValue` - // base (which provides cast/coalesce/from/serialize/column/deserialize - // /isNull/isNotNull/in). Everything else chains down through the pg_catalog - // hierarchy to `any`, so those methods are inherited transitively. - const parentTypname = pgType.typname === "any" - ? undefined - : extendsClass - ? Object.keys(EXTENDS_MAP).find((k) => pgNameToClassName(k) === extendsClass) - ?? "any" - : "anynonarray"; - if (pgType.typname === "any") { - lines.push('import { SqlValue } from "../../sql-value";'); - } else if (parentTypname) { - const parentClass = pgNameToClassName(parentTypname); - const dir = overrideNames.has(parentTypname) ? "overrides" : "generated"; - lines.push(`import { ${parentClass} } from "../${dir}/${parentTypname}";`); - } - - lines.push('import * as types from "../index";'); - - lines.push(""); - - // Build class declaration. Explicit `in out N` variance annotation skips - // TS's structural variance inference, which otherwise walks the full method - // surface across 77 concrete classes × ~100 mutually-referencing methods - // and recurses deep enough to overflow stock tsc's default stack. With the - // annotation, stock tsc typechecks cleanly in ~1.5s at default stack. - let classDecl = `export class ${pgType.className}`; - if (needsGenericT) { - classDecl += `, in out N extends number>`; - } else { - classDecl += ``; - } - if (extendsClass) { - // Parent takes T only if it's a container itself. - classDecl += parentIsContainer - ? ` extends ${extendsClass}` - : ` extends ${extendsClass}`; - } else if (pgType.typname === "any") { - classDecl += ` extends SqlValue`; - } else { - classDecl += ` extends Anynonarray`; - } - classDecl += " {"; - lines.push(classDecl); - - // [meta]: typed metadata bag hidden behind a symbol for clean autocomplete. - // Contains __class, __nullable, __nonNullable for type-level utilities. - // deserialize(): defined on Any override via registry, concrete types narrow the return type. - if (pgType.typname === "any") { - // Handled by override — no-op here - } else if (!EXTENDS_MAP[pgType.typname]) { - // Concrete type — narrow [meta]. For classes with no hand-written - // override under overrides/, emit a `declare deserialize` return-type - // marker so `TsTypeOf>` narrows (SqlValue.deserialize returns - // `unknown`). For classes with an override, the override provides - // both the runtime parser AND the narrower return type — codegen - // skips the declare to avoid a contradictory signature. - const cls = pgType.className; - const ref = overrideNames.has(pgType.typname) ? `types.${cls}` : cls; - // Subclass [meta] redeclarations replace the parent's — repeat __raw - // and __nullability from Any to keep them visible on concrete instances. - lines.push(` declare [meta]: {`); - lines.push(` __class: typeof ${ref};`); - lines.push(` __raw: runtime.Sql;`); - lines.push(` __nullability: N;`); - lines.push(` __nullable: ${ref}<0 | 1>;`); - lines.push(` __nonNullable: ${ref}<1>;`); - lines.push(` __aggregate: ${ref};`); - lines.push(` __any: ${ref};`); - lines.push(` };`); - lines.push(` static __typname = runtime.sql\`${pgType.typname}\`;`); - lines.push(` static __typnameText = "${pgType.typname}";`); - if (!overrideNames.has(pgType.typname)) { - lines.push(` declare deserialize: (raw: string) => ${primitiveTsFor(pgType.typname)};`); - } - } else { - // any* hierarchy type — inherits [meta] from parent, no re-declaration needed - } - - // --- Method codegen helpers --- - - // Build generic param + TS type for a single arg - const buildArgGeneric = (oid: number, i: number, allowPrimitive: boolean): string => { - const resolved = resolveBaseTypeName(oid, pgType, typeMap); - const constraint = formatTypeWithNull(resolved, "any"); - const t = typeMap.get(oid); - if (!t) { return `M${i} extends ${constraint}`; } - if (GENERIC_TYPES.has(t.typname) && needsGenericT) { - return `M${i} extends ${constraint}${allowPrimitive ? " | runtime.TsTypeOf[]" : ""}`; - } - if (ELEMENT_TYPES.has(t.typname) && needsGenericT) { - return `M${i} extends ${constraint}${allowPrimitive ? " | runtime.TsTypeOf" : ""}`; - } - if (GENERIC_TYPES.has(t.typname) || ELEMENT_TYPES.has(t.typname)) { - return `M${i} extends ${constraint}`; - } - return allowPrimitive - ? `M${i} extends ${constraint} | ${primitiveTsFor(t.typname)}` - : `M${i} extends ${constraint}`; - }; - - // Build return type string for a function - const buildRetType = (f: PgFunc): string => { - const retBase = resolveBaseTypeName(f.returnType, pgType, typeMap); - const restArgs = f.argTypes.slice(1); - if (f.isAggregate) { - return formatTypeWithNull(retBase, f.name === "count" ? "1" : "0 | 1"); - } - const nullParts = ["N", ...restArgs.map((_, i) => `runtime.NullOf`)]; - const nullUnion = nullParts.join(" | "); - if (MAYBE_NULL_OPS.has(f.name)) { - return formatTypeWithNull(retBase, `runtime.MaybeNull<${nullUnion}>`); - } - if (!f.isStrict) { - return formatTypeWithNull(retBase, "1"); - } - if (restArgs.length === 0) { - return formatTypeWithNull(retBase, "N"); - } - return formatTypeWithNull(retBase, `runtime.StrictNull<${nullUnion}>`); - }; - - // Runtime expression for a function's return-type constructor. - // For methods on abstract hierarchy types, the actual concrete class isn't - // known statically — resolve via pgElement(this) (container → element) or - // pgType(this) (abstract → self). Otherwise use the concrete class directly. - const runtimeRetType = (f: PgFunc): string => { - const retBase = resolveBaseTypeName(f.returnType, pgType, typeMap); - if (retBase.kind === "T") { return "runtime.pgElement(this)"; } - if (f.returnType === f.argTypes[0] && (isGeneric || isElement)) { return "runtime.pgType(this)"; } - const retT = typeMap.get(f.returnType); - return retT ? `types.${retT.className}` : `types.${pgType.className}`; - }; - - // Build a match case string: [[{type, allowPrimitive?}, ...], retType] - const buildMatchCase = (f: PgFunc, allowPrimitive: boolean): string => { - const matchers = f.argTypes.slice(1).map((oid) => { - const t = typeMap.get(oid); - if (!t) { return `{ type: types.Any }`; } - return allowPrimitive - ? `{ type: types.${t.className}, allowPrimitive: true }` - : `{ type: types.${t.className} }`; - }); - return `[[${matchers.join(", ")}], ${runtimeRetType(f)}]`; - }; - - // Whether an overload's args are all the owner's own pg type. - const argsMatchOwner = (f: PgFunc): boolean => - f.argTypes.slice(1).every((oid) => { - const t = typeMap.get(oid); - return t !== undefined && t.typname === pgType.typname; - }); - - // Decide allowPrimitive per overload within a group. Two pg types can - // share a TS primitive (e.g. int8 and inet are both `string` in JS), so - // letting both overloads accept that primitive lets TS pick the wrong - // one — `int8.plus("100")` would resolve to the inet overload. Rule: - // - // - Group overloads by their TS-primitive signature across args. - // - If a primitive-sig group has the owner-typed overload, only it - // accepts primitives (others require explicit casts). - // - If a primitive-sig group has multiple non-owner overloads, none - // accept primitives — caller must cast. - // - Singleton primitive sig: the overload accepts primitives. - const computeAllowPrimitive = (group: PgFunc[]): Map => { - const primSig = (f: PgFunc): string => - f.argTypes.slice(1) - .map((oid) => { - const t = typeMap.get(oid); - return t ? primitiveTsFor(t.typname) : ""; - }) - .join("|"); - - const byPrimSig = new Map(); - for (const f of group) { - const k = primSig(f); - if (!byPrimSig.has(k)) { byPrimSig.set(k, []); } - byPrimSig.get(k)!.push(f); - } - - const out = new Map(); - for (const overloads of byPrimSig.values()) { - if (overloads.length === 1) { - out.set(overloads[0]!, true); - } else { - const ownerOverload = overloads.find((o) => argsMatchOwner(o)); - for (const o of overloads) { - out.set(o, o === ownerOverload); - } - } - } - return out; - }; - - // Method name(s) as emitted. Operators get the bracketed form plus a - // readable alias if one is defined (eq/lt/plus/…); pg's catalog - // doesn't give these a nice function name, so codegen synthesizes one. - // Functions get just the camelcased pg name. - const methodName = (f: PgFunc): string => - f.isOperator ? `['${f.name}']` : camelcase(f.name); - const aliasName = (f: PgFunc): string | null => - f.isOperator && f.name in OPERATOR_ALIASES ? OPERATOR_ALIASES[f.name]! : null; - - // Build the "header" of a method signature: name + generic decl + params. - // `nameOverride` lets us emit the same signature under an alias name - // (e.g. `eq` next to `['=']`). - const buildSig = (f: PgFunc, allowPrimitive: boolean, nameOverride?: string): string => { - const restArgs = f.argTypes.slice(1); - const genericDecl = restArgs.length > 0 - ? `<${restArgs.map((oid, i) => buildArgGeneric(oid, i, allowPrimitive)).join(", ")}>` - : ""; - const params = restArgs.map((_, i) => `arg${i}: M${i}`).join(", "); - return `${nameOverride ?? methodName(f)}${genericDecl}(${params})`; - }; - - // Build the runtime body: match dispatch + caller. Uniform across 0-arg, - // n-arg, functions, operators, and single-column SRFs — the only thing - // that changes is which runtime entry point wraps __rt. `...__rest` spread - // tolerates overloads of differing arity within the same group. - const buildBody = (funcs: PgFunc[], allowMap: Map): string => { - const f0 = funcs[0]!; - const maxArity = Math.max(...funcs.map((f) => f.argTypes.length - 1)); - const inputArgs = Array.from({ length: maxArity }, (_, i) => `arg${i}`); - const cases = funcs.map((fn) => buildMatchCase(fn, allowMap.get(fn) ?? false)); - const matchCall = `runtime.match([${inputArgs.join(", ")}], [${cases.join(", ")}])`; - const caller = f0.isSrf - ? `new runtime.Srf("${f0.name}", [this, ...__rest], [["${f0.name}", __rt]])` - : f0.isOperator - ? `runtime.opCall(runtime.sql\`${f0.name}\`, [this, ...__rest] as [unknown, unknown], __rt)` - : `runtime.funcCall("${f0.name}", [this, ...__rest], __rt)`; - return `const [__rt, ...__rest] = ${matchCall}; return ${caller} as any;`; - }; - - // Wrap a bare pg return type for SRFs: `Int4` → `PgSrf<{ name: Int4 }, "name">`. - const wrapSrfRet = (f: PgFunc, retType: string): string => - `runtime.Srf<{ ${f.name}: ${retType} }, "${f.name}">`; - - // --- Emit methods --- - - // One loop handles: functions, operators, and single-column SRFs. Every - // group goes through match; signatures become TS overloads when the pg - // overload set has more than one entry. - // Multi-column SRFs are handled separately below (row shape is driven by - // OUT params, not by args, so match doesn't apply). - const allGroups = [...funcGroups.values(), ...operatorGroups.values()]; - for (const group of allGroups) { - const f0 = group[0]!; - - // Multi-column SRF: special-cased, shape comes from outColumns. - if (f0.isSrf && f0.outColumns && f0.outColumns.length > 0) { - const restArgs = f0.argTypes.slice(1); - const argNames = restArgs.map((_, i) => `arg${i}`); - const allArgs = argNames.length > 0 ? `this, ${argNames.join(", ")}` : "this"; - const colEntries = f0.outColumns.map((c) => { const t = typeMap.get(c.typeOid)!; return `${c.name}: types.${t.className}<1>`; }); - const colRuntime = f0.outColumns.map((c) => { const t = typeMap.get(c.typeOid)!; return `["${c.name}", types.${t.className}]`; }); - const sig = buildSig(f0, true); - const ret = `runtime.Srf<{ ${colEntries.join("; ")} }, "${f0.name}">`; - lines.push(` @expose.unchecked()`); - lines.push(` ${sig}: ${ret} { return new runtime.Srf("${f0.name}", [${allArgs}], [${colRuntime.join(", ")}]) as any; }`); - continue; - } - - const wrapRet = f0.isSrf ? wrapSrfRet : (_: PgFunc, r: string) => r; - // Skip the alias if pg already has a function with that name on this - // type (e.g. `mod`, `pow`) — the pg function wins, its signature is - // authoritative, and a synthesized alias would collide. - const rawAlias = aliasName(f0); - const alias = rawAlias && !funcGroups.has(rawAlias) ? rawAlias : null; - - const emit = (nameOverride?: string): void => { - const allowMap = computeAllowPrimitive(group); - if (group.length === 1) { - const sig = buildSig(f0, allowMap.get(f0) ?? true, nameOverride); - const retType = wrapRet(f0, buildRetType(f0)); - lines.push(` @expose.unchecked()`); - lines.push(` ${sig}: ${retType} { ${buildBody(group, allowMap)} }`); - return; - } - // Multiple overloads: emit TS overload signatures, then one typed-as-any - // implementation dispatching via match with the same per-overload - // primitive flags. The decorator goes on the implementation only — TS - // forbids decorators on overload signatures. - for (const overload of group) { - const sig = buildSig(overload, allowMap.get(overload) ?? false, nameOverride); - const retType = wrapRet(overload, buildRetType(overload)); - lines.push(` ${sig}: ${retType};`); - } - // Impl sig must cover all arities — required up to min, optional up to max. - const arities = group.map((f) => f.argTypes.length - 1); - const minArity = Math.min(...arities); - const maxArity = Math.max(...arities); - const implParams = Array.from({ length: maxArity }, (_, i) => - `arg${i}${i >= minArity ? "?" : ""}: unknown`, - ).join(", "); - lines.push(` @expose.unchecked()`); - lines.push(` ${nameOverride ?? methodName(f0)}(${implParams}): any { ${buildBody(group, allowMap)} }`); - }; - - emit(); - if (alias) { emit(alias); } - } - - lines.push("}"); - lines.push(""); - - return lines.join("\n"); -}; - -const scanOverrides = (): Set => { - const overrides = new Set(); - if (fs.existsSync(OVERRIDES_DIR)) { - for (const file of fs.readdirSync(OVERRIDES_DIR)) { - if (file.endsWith(".ts")) { - overrides.add(file.replace(".ts", "")); - } - } - } - return overrides; -}; - -const generateIndex = (typeMap: Map, overrides: Set) => { - - const lines: string[] = []; - lines.push("// Auto-generated block — do not edit between markers"); - lines.push("// [generated-start]"); - - const sortedTypes = [...typeMap.values()].sort((a, b) => - a.typname.localeCompare(b.typname), - ); - - for (const t of sortedTypes) { - if (overrides.has(t.typname)) { - lines.push( - `export { ${t.className} } from "./overrides/${t.typname}";`, - ); - } else { - lines.push( - `export { ${t.className} } from "./generated/${t.typname}";`, - ); - } - } - - lines.push("// [generated-end]"); - lines.push(""); - - return lines.join("\n"); -}; - -export const generate = async () => { - const db = new pg.Pool({ connectionString: requireDatabaseUrl() }); - - try { - const { typeMap, pgFuncs } = await introspect(db, Object.keys(OPERATOR_ALIASES)); - const grouped = groupByFirstArg(pgFuncs); - const overrideNames = scanOverrides(); - - // Clean generated dir - fs.rmSync(GENERATED_DIR, { recursive: true, force: true }); - fs.mkdirSync(GENERATED_DIR, { recursive: true }); - - // Generate a file per type - for (const [oid, pgType] of typeMap) { - const funcs = grouped.get(oid) ?? []; - const content = generateTypeFile(pgType, funcs, typeMap, overrideNames); - const filePath = path.join(GENERATED_DIR, `${pgType.typname}.ts`); - fs.writeFileSync(filePath, content); - } - - // Generate index - const indexContent = generateIndex(typeMap, overrideNames); - fs.writeFileSync(TYPES_INDEX, indexContent); - - console.log(`Generated ${typeMap.size} types in ${GENERATED_DIR}`); - } finally { - await db.end(); - } -}; - -// Run only when executed directly, not when imported. -if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { - generate().catch((err) => { - console.error(err); - process.exit(1); - }); -} diff --git a/src/types/runtime.ts b/src/types/runtime.ts index 51712d4a..7d83962f 100644 --- a/src/types/runtime.ts +++ b/src/types/runtime.ts @@ -1,7 +1,7 @@ export type { Sql } from "../builder/sql"; export { sql, Srf } from "../builder/sql"; import type { Raw } from "../builder/sql"; -import { Func, Op, argToSql } from "../builder/sql"; +import { Func, Op, UnaryOp, argToSql } from "../builder/sql"; import { SqlValue, meta } from "./sql-value"; import type { Any } from "./postgres"; import { isPlainData } from "../util"; @@ -93,7 +93,7 @@ export const isSetRow = (row: unknown): row is SetRow => { return false; } // Each value must be either a typegres expression (any dialect — - // PG's Any or SQLite's SqliteValue both extend SqlValue) OR plain + // PG's Any or SQLite's Any both extend SqlValue) OR plain // data (recursively — no other class instances at any depth). return Object.values(row).every( (v) => v instanceof SqlValue || isPlainData(v), @@ -101,8 +101,9 @@ export const isSetRow = (row: unknown): row is SetRow => { }; // Runtime type resolution -// pgType(expr) — returns the constructor via [meta].__class (set once in Any, narrowed by subclasses) -export const pgType = (expr: Any): typeof Any => expr[meta].__class as typeof Any; +// pgType(expr) — returns the constructor via [meta].__class (set once +// in SqlValue, narrowed by subclasses). Dialect-agnostic: any SqlValue. +export const pgType = (expr: SqlValue): typeof SqlValue => expr[meta].__class as typeof SqlValue; // pgElement(expr) — returns the element type constructor from a container's __element export const pgElement = (expr: Any): typeof Any => (expr[meta].__class as any).__element; @@ -111,36 +112,35 @@ export const pgElement = (expr: Any): typeof Any => (expr[meta].__class as // allowPrimitive: true if the corresponding TS primitive is accepted for this arg. // `type` is widened to `typeof SqlValue` so both PG- and SQLite-codegen // call sites typecheck (both dialects' classes descend from SqlValue). -type ArgMatcher = { type: typeof SqlValue; allowPrimitive?: boolean }; +type ArgMatcher = { + type: typeof SqlValue; + allowPrimitive?: boolean; + // Last matcher only: every argument beyond the fixed prefix is + // validated/serialized against this matcher (variadic tails). + rest?: boolean; +}; type MatchCase = [args: ArgMatcher[], retType: typeof SqlValue]; // Validates args, serializes primitives, and returns [retType, ...serializedArgs]. // The caller destructures: const [retType, ...args] = match(...) export const match = (args: unknown[], cases: MatchCase[]): [typeof SqlValue, ...unknown[]] => { + // Trailing undefined = optional args the caller omitted (fixed-arity + // impl signatures forward them as explicit undefined). + const given = [...args]; + while (given.length > 0 && given[given.length - 1] === undefined) { given.pop(); } + for (const [matchers, retType] of cases) { - const matched = matchers.every((m, i) => { - const arg = args[i]; - if (arg instanceof m.type) { - return true; - } - if (m.allowPrimitive) { - if (typeof arg === m.type.primitiveTs) { - return true; - } - } - return false; - }); - if (matched) { - const serialized = matchers.map((m, i) => { - if (args[i] instanceof m.type) { - return args[i]; - } - return m.type.serialize(args[i]); - }); - return [retType, ...serialized]; - } + // Assign each given arg its matcher: positional, with a trailing + // rest matcher repeating over any surplus. No assignment for every + // arg (or leftover required matchers) ⇒ the case is out. + const rest = matchers.at(-1)?.rest ? matchers.at(-1) : undefined; + const fixed = rest ? matchers.slice(0, -1) : matchers; + if (given.length < fixed.length || (given.length > fixed.length && !rest)) { continue; } + const slots = given.map((_, i) => fixed[i] ?? rest!); + if (!slots.every((m, i) => given[i] instanceof m.type || (!!m.allowPrimitive && m.type.acceptsPrimitive(given[i])))) { continue; } + return [retType, ...given.map((arg, i) => (arg instanceof slots[i]!.type ? arg : slots[i]!.type.serialize(arg)))]; } - throw new Error(`No matching overload for args: [${args.map((a) => typeof a).join(", ")}]`); + throw new Error(`No matching overload for args: [${given.map((a) => typeof a).join(", ")}]`); }; // Expression node builders — construct real typed instances via @@ -158,3 +158,7 @@ export const funcCall = (name: string, args: unknown[], type: typeof SqlValue) = export const opCall = (op: Raw, args: [unknown, unknown], type: typeof SqlValue) => { return type.from(new Op(op, argToSql(args[0]), argToSql(args[1]), type.dialect.name)); }; + +export const unaryOpCall = (op: Raw, arg: unknown, type: typeof SqlValue) => { + return type.from(new UnaryOp(op, argToSql(arg), type.dialect.name)); +}; diff --git a/src/types/sql-value.ts b/src/types/sql-value.ts index eff15e8e..3d62a083 100644 --- a/src/types/sql-value.ts +++ b/src/types/sql-value.ts @@ -72,6 +72,14 @@ export class SqlValue { // set this to `"number"` / `"boolean"` (int4, bool, ...). static primitiveTs: string = "string"; + // Whether `v` is an acceptable JS-side primitive for this class. + // The default is the historical typeof check; classes whose + // primitive has no distinct typeof override it (sqlite Blob → + // Uint8Array, sqlite Any → any plain data). + static acceptsPrimitive(v: unknown): boolean { + return typeof v === this.primitiveTs; + } + // Default: identity. Overrides on the ~6 non-string typed classes // (Bool → boolean, Int2/Int4/Oid → parseInt, Float4/Float8 → parseFloat) // return the parsed value. Return-typed as `unknown` here so subclass @@ -127,8 +135,9 @@ export class SqlValue { // silently wraps it as `Param(anAny)` which serializes as `{}`, // producing either invalid SQL or a confusing cast error far // from the call site. Plain objects (jsonb), arrays, nulls, - // and primitives are fine. - if (!isPlainData(v)) { + // and primitives are fine — as is Uint8Array, the one class + // instance that IS a bindable SQL value (blob/bytea). + if (!(v instanceof Uint8Array) && !isPlainData(v)) { const name = (Object.getPrototypeOf(v) as { constructor?: { name?: string } } | null)?.constructor?.name ?? "anonymous"; throw new TypeError( `${this.__typnameText}.from: cannot wrap ${name} instance as a typegres parameter. ` + @@ -136,7 +145,14 @@ export class SqlValue { `otherwise extract the primitive value first.`, ); } - __raw = new TypedParam(new Param(v), this.__typname, this.dialect.name); + // `any` is a placeholder, not a castable type name — a TypedParam + // would compile to CAST(? AS any), which SQLite resolves to + // NUMERIC affinity (mangling '!' → 0) and PG rejects. Root + // classes bind bare params; concrete classes keep the forced + // cast that makes their type claims true. + __raw = this.__typnameText === "any" + ? new Param(v) + : new TypedParam(new Param(v), this.__typname, this.dialect.name); } // Set [meta] at runtime — subclasses' `declare [meta]` narrows the type only Object.defineProperty(instance, meta, { @@ -150,10 +166,9 @@ export class SqlValue { // Used by match() for runtime overload dispatch. static serialize(v: unknown): SqlValue { if (v instanceof this) { return v; } - const expected = this.primitiveTs; - if (typeof v === expected) { return this.from(v); } + if (this.acceptsPrimitive(v)) { return this.from(v); } throw new Error( - `${this.__typnameText}.serialize: expected a ${this.__typnameText} instance or ${expected} primitive, got ${typeof v} (${String(v).slice(0, 60)}).`, + `${this.__typnameText}.serialize: expected a ${this.__typnameText} instance or an accepted primitive, got ${typeof v} (${String(v).slice(0, 60)}).`, ); } diff --git a/src/types/sqlite/base.ts b/src/types/sqlite/base.ts deleted file mode 100644 index e6d7713d..00000000 --- a/src/types/sqlite/base.ts +++ /dev/null @@ -1,86 +0,0 @@ -// SQLite-side root class. Sits directly below `SqlValue` (SQLite has -// no polymorphic pseudotype hierarchy the way PG does — Integer, Text, -// Real, Blob, Json, Bool all extend SqliteValue directly). -// -// Mirrors PG `Any`: carries dialect metadata + the three Bool-returning -// methods (isNull/isNotNull/in) that couldn't live on the shared -// SqlValue for variance reasons (see src/types/sql-value.ts docstring). -// -// `dialect.root` / `dialect.bool` use barrel-import getters so the -// class-level dialect object can be initialized at class-def time -// without resolving the cyclic references at import time. Property -// access happens at method-call time. -// -import z from "zod"; -import { SqlValue, type Dialect } from "../sql-value"; -import { meta } from "../sql-value"; -import * as types from "./index"; -import { sql, type Sql } from "../../builder/sql"; -import { expose } from "../../exoeval/tool"; -import { isPlainData } from "../../util"; - -export class SqliteValue extends SqlValue { - declare [meta]: { - __class: typeof SqliteValue; - __raw: Sql; - __nullability: N; - __aggregate: SqliteValue; - }; - static override dialect: Dialect = { - name: "sqlite", - get root() { return types.SqliteValue; }, - get bool() { return types.Bool; }, - }; - static override __typname = sql`any`; - static override __typnameText = "any"; - - isNull(): types.Bool<1> { - return types.Bool.from(sql`(${this.toSql()} IS NULL)`) as types.Bool<1>; - } - - isNotNull(): types.Bool<1> { - return types.Bool.from(sql`(${this.toSql()} IS NOT NULL)`) as types.Bool<1>; - } - - // Equality against another SqliteValue instance or a JS primitive. - // SQLite is manifest-typed at runtime, so no per-class overload - // narrowing — the shared surface takes any comparable value. - // Primitives get parameterized as-is via sql.param; instances - // splice their .toSql(). - // - // @expose so exoeval-sandboxed predicates (RPC/tool-driven .where() - // callbacks) can call it — parity with PG's codegen'd operator - // methods, which are all exposed. - @expose(z.union([z.custom>((v) => v instanceof SqliteValue), z.boolean(), z.number(), z.string()])) - eq(other: SqliteValue | boolean | number | string): types.Bool { - const rhs = other instanceof SqliteValue ? other.toSql() : sql.param(other); - return types.Bool.from(sql`(${this.toSql()} = ${rhs})`) as types.Bool; - } - - // Non-generic `.in()` — SQLite's shallow class hierarchy (SqlValue → - // SqliteValue → concrete) triggers TS2589 with the PG-style - // `, Vs>(this: T, ...)` signature, because - // each concrete class's `[meta].__any: Concrete` self-reference - // never bottoms out at that depth. PG dodges the recursion via a - // deeper 7-level chain. - // - // Trade-off: users don't get "same-typed args required" narrowing at - // compile time. Runtime enforcement via serialize() still applies. - // eslint-disable-next-line no-restricted-syntax - @expose.unchecked() - in(...vals: [SqliteValue | boolean | number | string, ...(SqliteValue | boolean | number | string)[]]): types.Bool { - const wrapped = vals.map((v) => { - if (v instanceof SqliteValue) {return v;} - if (!isPlainData(v)) { - const name = (Object.getPrototypeOf(v) as { constructor?: { name?: string } } | null)?.constructor?.name ?? "anonymous"; - throw new TypeError( - `SqliteValue.in: cannot accept ${name} instance as a list value. ` + - `Pass a typegres expression or a primitive matching ${(this[meta].__class as typeof SqliteValue).__typnameText}.`, - ); - } - return this[meta].__class.serialize(v); - }); - const list = sql.join(wrapped.map((v) => v.toSql())); - return types.Bool.from(sql`(${this.toSql()} IN (${list}))`) as types.Bool; - } -} diff --git a/src/types/sqlite/docs/.gitignore b/src/types/sqlite/docs/.gitignore new file mode 100644 index 00000000..fbe5e9cd --- /dev/null +++ b/src/types/sqlite/docs/.gitignore @@ -0,0 +1,4 @@ +# Fetched doc pages — reproduce with ./fetch.sh (see VERSION for the +# snapshot stamp). Committed: fetch.sh, VERSION, index.ts (schema + +# extraction prompt), and the *.json extraction artifacts. +*.html diff --git a/src/types/sqlite/docs/VERSION b/src/types/sqlite/docs/VERSION new file mode 100644 index 00000000..37c4c61e --- /dev/null +++ b/src/types/sqlite/docs/VERSION @@ -0,0 +1,3 @@ +fetched_at: 2026-07-10T20:50:34Z +source: https://www.sqlite.org/ (current release docs) +target_sqlite_version: 3.53.2 diff --git a/src/types/sqlite/docs/fetch.sh b/src/types/sqlite/docs/fetch.sh new file mode 100755 index 00000000..aa60561c --- /dev/null +++ b/src/types/sqlite/docs/fetch.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Vendor the SQLite doc pages that drive signatures.json (the +# function/operator definition pipeline — see plan.md). +# +# sqlite.org serves current-release docs only; we stamp VERSION with +# the sqlite_version() the definitions target so the verifier can +# flag drift between the docs snapshot and the SQLite that +# better-sqlite3 actually embeds. +set -euo pipefail +cd "$(dirname "$0")" + +PAGES=( + lang_corefunc.html # core scalar functions + lang_mathfunc.html # math functions + lang_datefunc.html # date/time functions + modifier mini-language + lang_aggfunc.html # aggregate functions + windowfunctions.html # window functions + json1.html # JSON functions + -> / ->> operators + lang_expr.html # expressions: full operator precedence table, LIKE/GLOB/BETWEEN/IS + datatype3.html # type affinity + comparison coercion rules + printf.html # format()/printf() format-string language + percentile.html # median()/percentile() aggregate extension +) + +for page in "${PAGES[@]}"; do + echo "fetching $page" + curl -fsSL "https://www.sqlite.org/$page" -o "$page" +done + +# Record what we fetched and the SQLite version the definitions target. +{ + echo "fetched_at: $(date -u +%Y-%m-%dT%H:%M:%SZ)" + echo "source: https://www.sqlite.org/ (current release docs)" + node -e 'import("better-sqlite3").then(m => { + const db = new m.default(":memory:"); + console.log("target_sqlite_version: " + db.prepare("SELECT sqlite_version() v").get().v); + db.close(); + })' 2>/dev/null || echo "target_sqlite_version: unknown (better-sqlite3 not resolvable)" +} > VERSION + +echo "done — $(ls -1 *.html | wc -l) pages, see VERSION" diff --git a/src/types/sqlite/docs/index.ts b/src/types/sqlite/docs/index.ts new file mode 100644 index 00000000..7840bd02 --- /dev/null +++ b/src/types/sqlite/docs/index.ts @@ -0,0 +1,195 @@ +// Doc-extraction contract for the SQLite signature pipeline. +// +// Each vendored .html page (see fetch.sh) has a sibling .json holding +// the FACTS extracted from that page — one file per page, 1:1, so a +// SQLite version bump is: re-run fetch.sh, re-extract the changed +// page(s) with EXTRACTION_PROMPT, review a tight JSON diff, re-verify. +// +// The JSONs hold doc-derived facts ONLY — and the library surface is +// DERIVED from them by global rules in ../emit.ts (args in exact SQL +// call order; method receivers = the FIRST argument's documented +// domain; names = camelCase(sql) / operator symbol + alias). +// There is no per-function policy layer: the only remaining judgment +// lives in ../emit.ts's EXCLUSIONS list and the emit rules +// themselves. This keeps the 1:1 claim strict — an extraction file is +// checkable against its page alone — and makes extraction fidelity +// load-bearing: the receiver argument's documented domain is what +// decides which typed views surface a method. +// +// The structural schema is shared with postgres (emission/facts.ts); +// this file adds the sqlite-only refinements and the extraction +// prompt. ../emit.ts loads + zod-validates every JSON at module load +// into SIGNATURES. The property verifier (signatures.verify.test.ts) +// remains the correctness oracle for every claim in these files. + +import z from "zod"; +import { + EmitFnSchema, + type EmitArg, + type EmitOverload, + type EmitFn, +} from "../../emission/facts.ts"; +export type { Nullability } from "../../emission/facts.ts"; + +// --- schema --------------------------------------------------------------- +// The structural schema is the SHARED facts contract +// (../../emission/facts.ts) — the same shape postgres produces from +// its catalog. What's sqlite-specific is the extra validation the +// LLM-extracted JSONs get: the storage-class and hint vocabularies, +// required docs, and pg-only fields rejected. + +export const SqlTSchema = z.enum(["integer", "real", "text", "blob", "bool", "any"]); + +// Semantic domain of an argument, when the docs constrain it beyond a +// storage class. Drives the verifier's input generators. +export const HintSchema = z.enum([ + "json", "jsonpath", "json-array", "jsonpath-element", "plain", + "datetime", "datetime-modifier", "strftime-format", + "printf-format", "like-pattern", "escape-char", + "percent", "fraction", "unit-interval", "byte-count", +]); + +export const DocPageSchema = z + .object({ + page: z.string(), // the .html this was extracted from + functions: z.array(EmitFnSchema), + }) + .superRefine((page, ctx) => { + page.functions.forEach((f, fi) => { + const issue = (message: string, path: (string | number)[]): void => { + ctx.addIssue({ code: "custom", message, path: ["functions", fi, ...path] }); + }; + if (!f.doc) { issue(`${f.sql}: doc is required`, ["doc"]); } + if (f.isSrf) { + if (!f.outColumns?.length) { issue(`${f.sql}: isSrf requires outColumns`, ["outColumns"]); } + for (const [ci, c] of (f.outColumns ?? []).entries()) { + if (!SqlTSchema.safeParse(c.type).success) { issue(`${f.sql}: unknown storage class '${c.type}'`, ["outColumns", ci, "type"]); } + } + } else if (f.outColumns) { + issue(`${f.sql}: outColumns without isSrf`, ["outColumns"]); + } + f.overloads.forEach((o, oi) => { + const at = (rest: (string | number)[]): (string | number)[] => ["overloads", oi, ...rest]; + if (o.nullability === "maybe_null") { issue(`${f.sql}: maybe_null is pg-only`, at(["nullability"])); } + const retOk = f.isSrf + ? o.returns === null // the SRF row shape lives in outColumns + : o.returns === "arg0" || SqlTSchema.safeParse(o.returns).success; + if (!retOk) { issue(`${f.sql}: invalid returns '${o.returns}'`, at(["returns"])); } + o.args.forEach((arg, ai) => { + if (arg.type === null || !SqlTSchema.safeParse(arg.type).success) { + issue(`${f.sql}: unknown storage class '${arg.type}'`, at(["args", ai, "type"])); + } + if (arg.hint !== undefined && !HintSchema.safeParse(arg.hint).success) { + issue(`${f.sql}: unknown hint '${arg.hint}'`, at(["args", ai, "hint"])); + } + }); + }); + }); + }); + +export type SqlT = z.infer; +export type Hint = z.infer; +export type ArgDef = EmitArg; +export type Overload = EmitOverload; +export type DocFunction = EmitFn; +export type DocPage = z.infer; + +// --- extraction prompt ------------------------------------------------------ +// Hand this, word for word, to a subagent along with ONE vendored +// .html page. Substitute {PAGE} with the page filename (e.g. +// "lang_corefunc.html"). The output replaces the sibling +// {PAGE_BASENAME}.json. + +export const EXTRACTION_PROMPT = ` +You are extracting SQLite function/operator signatures from one page +of the official SQLite documentation into a JSON facts file. Read the +file docs/{PAGE} completely, then output a single JSON document — no +prose, no markdown fences — conforming to the DocPage schema in +docs/index.ts (fields: page, functions[]; each function: sql, kind, +doc, deterministic?, isSrf?, outColumns?, overloads[]; each overload: +args[], variadic?, returns, nullability, nullPositions?; each arg: +type, hint?, optional?). + +Rules: + +1. FACTS ONLY, from this page alone. Do not decide which typegres + views expose a method, naming, or anything else about the + library — that is policy and lives elsewhere. If the page + documents it, extract it; if not, don't invent it. + +2. One entry per documented function or operator, keyed by its exact + SQL spelling in "sql" (lowercase function names; operator symbols + verbatim, e.g. "->>", "IS NOT"). kind: "scalar" | "aggregate" for + functions, "binop" | "unaryop" for operators. List args in the + function's EXACT documented call order — never reorder. The FIRST + argument is the method receiver, so its documented domain + determines which typed views surface the method; extract every + arg's domain faithfully: a function the page documents for JSON + values (text or JSONB blob) gets one overload per receiver class, + not a single "any". For lang_expr.html, + enumerate EVERY operator in the precedence table (that table is + the completeness inventory for operators) — except operators that + are query-builder syntax rather than value expressions (AND, OR, + NOT, IN, BETWEEN, CASE, CAST, COLLATE, EXISTS, LIKE/GLOB/REGEXP/ + MATCH keyword forms — LIKE and GLOB are extracted from + lang_corefunc.html as their function forms instead). + +3. Overloads: one per distinct arity/argument-type combination with + observable meaning. Use storage classes ("integer", "real", + "text", "blob") when the docs are specific; "any" when the + function accepts any value; "bool" only for true/false-valued + parameters and returns. For numeric functions documented for both + integer and real inputs with input-dependent returns, emit one + overload per input class. Mark trailing optional parameters with + "optional": true; mark "last argument repeats" with + "variadic": true. + Pairwise-repeating tails (json_set's path,value pairs) cannot be + expressed — cover one pair and note it in "doc". + +4. returns: the storage class the page says comes back; "arg0" when + the return type follows the first argument (abs, min/max + aggregates). + +5. For functions (not operators), set "deterministic": true unless the + page describes the result as random, connection-dependent, or + changing between identical calls (random, changes, + last_insert_rowid, ...). Statement-time 'now' counts as + deterministic. The verifier cross-checks this against the engine's + SQLITE_DETERMINISTIC flag, and non-deterministic functions are not + emitted to the typed surface. + +6. nullability — commit to exactly one, this is the hardest judgment + and the property verifier will catch mistakes: + - "propagates": NULL in → NULL out AND non-null valid in → + non-null out. + - "never": non-null even for NULL inputs (hex, quote, typeof). + - "always": can be NULL on valid non-null input (aggregates over + the empty set, nullif). + - "on_error": NULL is the error signal (date parsing, JSON paths, + domain errors like sqrt(-1), division by zero). + Use nullPositions (0-based) when only SOME argument positions + participate in NULL semantics (concat_ws: only the separator + propagates; json_object: labels may not be NULL at all). + +7. hint: attach the semantic domain the docs state for constrained + arguments — time values ("datetime"), modifiers + ("datetime-modifier"), strftime/printf format strings, JSON + documents ("json") and paths ("jsonpath"), LIKE patterns, ESCAPE + chars ("escape-char"), bounded fractions ("percent" 0..100, + "fraction" 0..1), allocation sizes ("byte-count" — zeroblob, + randomblob), and "plain" for JSON value positions (JSON cannot + hold BLOBs). Arguments to array-element operations use + "json-array" / "jsonpath-element". + +8. doc: one sentence, present tense, from the page's description — + include version notes the page states (e.g. "(3.44+)"). + +9. Table-valued (set-returning) functions the page documents + (json_each, json_tree): kind "scalar" with "isSrf": true and + "outColumns" listing the projected columns in order with their + storage classes ("any" where the class depends on the data). Their + overloads describe the CALL arguments as usual, with + "returns": null — the row shape lives in outColumns. + +Output only the JSON document. +`.trim(); diff --git a/src/types/sqlite/docs/json1.json b/src/types/sqlite/docs/json1.json new file mode 100644 index 00000000..37bfdea0 --- /dev/null +++ b/src/types/sqlite/docs/json1.json @@ -0,0 +1,1122 @@ +{ + "page": "json1.html", + "functions": [ + { + "sql": "json", + "kind": "scalar", + "doc": "Validate + minify JSON (jsonb \u2192 binary).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + } + ], + "returns": "text", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "jsonb", + "kind": "scalar", + "doc": "Validate + minify JSON (jsonb \u2192 binary).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + } + ], + "returns": "blob", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + } + ], + "returns": "blob", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_array", + "kind": "scalar", + "doc": "JSON array from the arguments.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "plain" + } + ], + "variadic": true, + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "jsonb_array", + "kind": "scalar", + "doc": "JSON array from the arguments.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "plain" + } + ], + "variadic": true, + "returns": "blob", + "nullability": "never" + } + ] + }, + { + "sql": "json_array_length", + "kind": "scalar", + "doc": "Array length at path (default '$').", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath", + "optional": true + } + ], + "returns": "integer", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath", + "optional": true + } + ], + "returns": "integer", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_error_position", + "kind": "scalar", + "doc": "0 if well-formed, else 1-based position of the first error.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + } + ], + "returns": "integer", + "nullability": "propagates" + } + ] + }, + { + "sql": "json_extract", + "kind": "scalar", + "doc": "Extract value(s) at path(s) \u2014 SQL value for scalars, JSON text otherwise.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "variadic": true, + "returns": "any", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "variadic": true, + "returns": "any", + "nullability": "on_error" + } + ] + }, + { + "sql": "jsonb_extract", + "kind": "scalar", + "doc": "Extract at path(s) \u2014 JSONB for objects/arrays, SQL value for scalars.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "variadic": true, + "returns": "any", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "variadic": true, + "returns": "any", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_insert", + "kind": "scalar", + "doc": "Insert value at path if absent (more path/value pairs may follow).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "jsonb_insert", + "kind": "scalar", + "doc": "Insert value at path if absent (more path/value pairs may follow).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_array_insert", + "kind": "scalar", + "doc": "Insert value into array at element path, shifting later elements (3.51+).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json-array" + }, + { + "type": "text", + "hint": "jsonpath-element" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json-array" + }, + { + "type": "text", + "hint": "jsonpath-element" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "jsonb_array_insert", + "kind": "scalar", + "doc": "Insert value into array at element path, shifting later elements (3.51+).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json-array" + }, + { + "type": "text", + "hint": "jsonpath-element" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json-array" + }, + { + "type": "text", + "hint": "jsonpath-element" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_object", + "kind": "scalar", + "doc": "JSON object from alternating key/value args (label args must be TEXT).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "never", + "nullPositions": [ + 1 + ] + } + ] + }, + { + "sql": "jsonb_object", + "kind": "scalar", + "doc": "JSON object from alternating key/value args (label args must be TEXT).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "never", + "nullPositions": [ + 1 + ] + } + ] + }, + { + "sql": "json_patch", + "kind": "scalar", + "doc": "RFC-7396 MergePatch of Y into X.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "any", + "hint": "json" + } + ], + "returns": "text", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "any", + "hint": "json" + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "jsonb_patch", + "kind": "scalar", + "doc": "RFC-7396 MergePatch of Y into X.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "any", + "hint": "json" + } + ], + "returns": "blob", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "any", + "hint": "json" + } + ], + "returns": "blob", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_pretty", + "kind": "scalar", + "doc": "Pretty-print JSON (3.46+).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "optional": true + } + ], + "returns": "text", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "optional": true + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_quote", + "kind": "scalar", + "doc": "SQL value \u2192 JSON representation.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "json_remove", + "kind": "scalar", + "doc": "Remove the value(s) at path(s).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "variadic": true, + "returns": "text", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "variadic": true, + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "jsonb_remove", + "kind": "scalar", + "doc": "Remove the value(s) at path(s).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "variadic": true, + "returns": "blob", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "variadic": true, + "returns": "blob", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_replace", + "kind": "scalar", + "doc": "Replace value at path if present (more path/value pairs may follow).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "jsonb_replace", + "kind": "scalar", + "doc": "Replace value at path if present (more path/value pairs may follow).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_set", + "kind": "scalar", + "doc": "Set value at path \u2014 insert or replace (more path/value pairs may follow).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "jsonb_set", + "kind": "scalar", + "doc": "Set value at path \u2014 insert or replace (more path/value pairs may follow).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_type", + "kind": "scalar", + "doc": "'object'|'array'|'integer'|... at path; NULL if path absent.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath", + "optional": true + } + ], + "returns": "text", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath", + "optional": true + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "json_valid", + "kind": "scalar", + "doc": "1 if X is well-formed RFC-8259 JSON text.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "propagates" + } + ] + }, + { + "sql": "json_group_array", + "kind": "aggregate", + "doc": "Aggregate values into a JSON array ('[]' for empty).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "jsonb_group_array", + "kind": "aggregate", + "doc": "Aggregate values into a JSONB array.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "never" + } + ] + }, + { + "sql": "json_group_object", + "kind": "aggregate", + "doc": "Aggregate key/value pairs into a JSON object.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "jsonb_group_object", + "kind": "aggregate", + "doc": "Aggregate key/value pairs into a JSONB object.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "any", + "hint": "plain" + } + ], + "returns": "blob", + "nullability": "never" + } + ] + }, + { + "sql": "json_each", + "kind": "scalar", + "isSrf": true, + "doc": "Table-valued: one row per element of the top-level array/object (or of the value at PATH).", + "deterministic": true, + "outColumns": [ + { + "name": "key", + "type": "any" + }, + { + "name": "value", + "type": "any" + }, + { + "name": "type", + "type": "text" + }, + { + "name": "atom", + "type": "any" + }, + { + "name": "id", + "type": "integer" + }, + { + "name": "parent", + "type": "integer" + }, + { + "name": "fullkey", + "type": "text" + }, + { + "name": "path", + "type": "text" + } + ], + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath", + "optional": true + } + ], + "returns": null, + "nullability": "never" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath", + "optional": true + } + ], + "returns": null, + "nullability": "never" + } + ] + }, + { + "sql": "json_tree", + "kind": "scalar", + "isSrf": true, + "doc": "Table-valued: recursive walk of the whole JSON tree, one row per container and leaf.", + "deterministic": true, + "outColumns": [ + { + "name": "key", + "type": "any" + }, + { + "name": "value", + "type": "any" + }, + { + "name": "type", + "type": "text" + }, + { + "name": "atom", + "type": "any" + }, + { + "name": "id", + "type": "integer" + }, + { + "name": "parent", + "type": "integer" + }, + { + "name": "fullkey", + "type": "text" + }, + { + "name": "path", + "type": "text" + } + ], + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath", + "optional": true + } + ], + "returns": null, + "nullability": "never" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath", + "optional": true + } + ], + "returns": null, + "nullability": "never" + } + ] + } + ] +} diff --git a/src/types/sqlite/docs/lang_aggfunc.json b/src/types/sqlite/docs/lang_aggfunc.json new file mode 100644 index 00000000..52fac4a6 --- /dev/null +++ b/src/types/sqlite/docs/lang_aggfunc.json @@ -0,0 +1,157 @@ +{ + "page": "lang_aggfunc.html", + "functions": [ + { + "sql": "avg", + "kind": "aggregate", + "doc": "Mean of non-NULL values; NULL over the empty set.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "returns": "real", + "nullability": "always" + } + ] + }, + { + "sql": "count", + "kind": "aggregate", + "doc": "Count of non-NULL values.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "returns": "integer", + "nullability": "never" + } + ] + }, + { + "sql": "group_concat", + "kind": "aggregate", + "doc": "Concatenation of non-NULL values with separator (default ',').", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "text", + "optional": true + } + ], + "returns": "text", + "nullability": "always" + } + ] + }, + { + "sql": "string_agg", + "kind": "aggregate", + "doc": "Alias of group_concat(X, SEP) (3.44+).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "text" + } + ], + "returns": "text", + "nullability": "always" + } + ] + }, + { + "sql": "max", + "kind": "aggregate", + "doc": "Maximum value; NULL over the empty set.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "returns": "arg0", + "nullability": "always" + } + ] + }, + { + "sql": "min", + "kind": "aggregate", + "doc": "Minimum value; NULL over the empty set.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "returns": "arg0", + "nullability": "always" + } + ] + }, + { + "sql": "sum", + "kind": "aggregate", + "doc": "Sum; NULL over the empty set; integer overflow throws.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "always" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "always" + } + ] + }, + { + "sql": "total", + "kind": "aggregate", + "doc": "Sum as REAL; 0.0 over the empty set, never NULL.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "returns": "real", + "nullability": "never" + } + ] + } + ] +} diff --git a/src/types/sqlite/docs/lang_corefunc.json b/src/types/sqlite/docs/lang_corefunc.json new file mode 100644 index 00000000..130dc430 --- /dev/null +++ b/src/types/sqlite/docs/lang_corefunc.json @@ -0,0 +1,947 @@ +{ + "page": "lang_corefunc.html", + "functions": [ + { + "sql": "abs", + "kind": "scalar", + "doc": "Absolute value. INTEGER in \u2192 INTEGER out; throws on INT64_MIN.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "char", + "kind": "scalar", + "doc": "String from unicode code points.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "variadic": true, + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "concat", + "kind": "scalar", + "doc": "Concatenation of all non-NULL args (3.44+).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "variadic": true, + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "concat_ws", + "kind": "scalar", + "doc": "Concatenation with separator, skipping NULLs (3.44+).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "any" + } + ], + "variadic": true, + "returns": "text", + "nullability": "propagates", + "nullPositions": [ + 0 + ] + } + ] + }, + { + "sql": "format", + "kind": "scalar", + "doc": "printf-style formatting (see printf.html).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "printf-format" + }, + { + "type": "any" + } + ], + "variadic": true, + "returns": "text", + "nullability": "propagates", + "nullPositions": [ + 0 + ] + } + ] + }, + { + "sql": "printf", + "kind": "scalar", + "doc": "Alias of format().", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "printf-format" + }, + { + "type": "any" + } + ], + "variadic": true, + "returns": "text", + "nullability": "propagates", + "nullPositions": [ + 0 + ] + } + ] + }, + { + "sql": "glob", + "kind": "scalar", + "doc": "X GLOB pattern \u2014 case-sensitive glob match (glob(P, X) function form).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "like-pattern" + }, + { + "type": "text" + } + ], + "returns": "bool", + "nullability": "propagates" + } + ] + }, + { + "sql": "hex", + "kind": "scalar", + "doc": "Uppercase hex rendering of the blob-coerced value; hex(NULL) = ''.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "instr", + "kind": "scalar", + "doc": "1-based position of the first occurrence of Y in X; 0 if absent.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "text" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "blob" + }, + { + "type": "blob" + } + ], + "returns": "integer", + "nullability": "propagates" + } + ] + }, + { + "sql": "length", + "kind": "scalar", + "doc": "Characters for TEXT, bytes for BLOB.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "blob" + } + ], + "returns": "integer", + "nullability": "propagates" + } + ] + }, + { + "sql": "like", + "kind": "scalar", + "doc": "X LIKE pattern [ESCAPE e] \u2014 case-insensitive (ASCII) pattern match.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "like-pattern" + }, + { + "type": "text" + } + ], + "returns": "bool", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "text", + "hint": "like-pattern" + }, + { + "type": "text" + }, + { + "type": "text", + "hint": "escape-char" + } + ], + "returns": "bool", + "nullability": "propagates" + } + ] + }, + { + "sql": "lower", + "kind": "scalar", + "doc": "ASCII lowercase.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + } + ], + "returns": "text", + "nullability": "propagates" + } + ] + }, + { + "sql": "ltrim", + "kind": "scalar", + "doc": "Trim chars (default whitespace) from the left.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "text", + "optional": true + } + ], + "returns": "text", + "nullability": "propagates" + } + ] + }, + { + "sql": "max", + "kind": "scalar", + "doc": "Scalar max of 2+ values (SQLite cross-type ordering).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "variadic": true, + "returns": "any", + "nullability": "propagates" + } + ] + }, + { + "sql": "min", + "kind": "scalar", + "doc": "Scalar min of 2+ values (SQLite cross-type ordering).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "variadic": true, + "returns": "any", + "nullability": "propagates" + } + ] + }, + { + "sql": "octet_length", + "kind": "scalar", + "doc": "Length in bytes after TEXT encoding.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "blob" + } + ], + "returns": "integer", + "nullability": "propagates" + } + ] + }, + { + "sql": "quote", + "kind": "scalar", + "doc": "SQL-literal rendering; quote(NULL) = 'NULL'.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "random", + "kind": "scalar", + "doc": "Pseudo-random INT64.", + "deterministic": false, + "overloads": [ + { + "args": [], + "returns": "integer", + "nullability": "never" + } + ] + }, + { + "sql": "randomblob", + "kind": "scalar", + "doc": "N pseudo-random bytes.", + "deterministic": false, + "overloads": [ + { + "args": [ + { + "type": "integer", + "hint": "byte-count" + } + ], + "returns": "blob", + "nullability": "never" + } + ] + }, + { + "sql": "replace", + "kind": "scalar", + "doc": "Replace every occurrence of Y with Z in X. Empty pattern short-circuits NULL propagation from Z.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "text" + }, + { + "type": "text" + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "round", + "kind": "scalar", + "doc": "Round to Y digits (default 0). Result is REAL.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer", + "optional": true + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "integer", + "optional": true + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "sign", + "kind": "scalar", + "doc": "-1, 0, or +1; NULL for non-numeric.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "integer", + "nullability": "propagates" + } + ] + }, + { + "sql": "soundex", + "kind": "scalar", + "doc": "Soundex encoding; '?000' for unmappable input.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + } + ], + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "substr", + "kind": "scalar", + "doc": "Substring from 1-based Y, length Z (to end if omitted). Empty-blob input yields NULL.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "integer" + }, + { + "type": "integer", + "optional": true + } + ], + "returns": "text", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "blob" + }, + { + "type": "integer" + }, + { + "type": "integer", + "optional": true + } + ], + "returns": "blob", + "nullability": "on_error" + } + ] + }, + { + "sql": "substring", + "kind": "scalar", + "doc": "Alias of substr(). Empty-blob input yields NULL.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "integer" + }, + { + "type": "integer", + "optional": true + } + ], + "returns": "text", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "blob" + }, + { + "type": "integer" + }, + { + "type": "integer", + "optional": true + } + ], + "returns": "blob", + "nullability": "on_error" + } + ] + }, + { + "sql": "rtrim", + "kind": "scalar", + "doc": "Trim chars (default whitespace) from the right.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "text", + "optional": true + } + ], + "returns": "text", + "nullability": "propagates" + } + ] + }, + { + "sql": "trim", + "kind": "scalar", + "doc": "Trim chars (default whitespace) from both ends.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "text", + "optional": true + } + ], + "returns": "text", + "nullability": "propagates" + } + ] + }, + { + "sql": "typeof", + "kind": "scalar", + "doc": "Storage class name: 'integer'|'real'|'text'|'blob'|'null'.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "unhex", + "kind": "scalar", + "doc": "Hex string \u2192 BLOB; NULL on non-hex input.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + }, + { + "type": "text", + "optional": true + } + ], + "returns": "blob", + "nullability": "on_error" + } + ] + }, + { + "sql": "unicode", + "kind": "scalar", + "doc": "Code point of the first character.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + } + ], + "returns": "integer", + "nullability": "on_error" + } + ] + }, + { + "sql": "unistr", + "kind": "scalar", + "doc": "Decode \\uXXXX escapes (3.50+).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "unistr_quote", + "kind": "scalar", + "doc": "quote() but escaping non-ASCII via \\u (3.50+).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + } + ], + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "upper", + "kind": "scalar", + "doc": "ASCII uppercase.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text" + } + ], + "returns": "text", + "nullability": "propagates" + } + ] + }, + { + "sql": "zeroblob", + "kind": "scalar", + "doc": "BLOB of N zero bytes.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer", + "hint": "byte-count" + } + ], + "returns": "blob", + "nullability": "never" + } + ] + }, + { + "sql": "coalesce", + "kind": "scalar", + "doc": "First non-NULL argument.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "variadic": true, + "returns": "any", + "nullability": "always" + } + ] + }, + { + "sql": "ifnull", + "kind": "scalar", + "doc": "coalesce() with exactly two args.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "any", + "nullability": "always" + } + ] + }, + { + "sql": "iif", + "kind": "scalar", + "doc": "iif(C, T, F) \u2014 T when C is true, else F.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "bool" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "any", + "nullability": "always" + } + ] + }, + { + "sql": "if", + "kind": "scalar", + "doc": "Alias of iif() (3.48+).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "bool" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "any", + "nullability": "always" + } + ] + }, + { + "sql": "nullif", + "kind": "scalar", + "doc": "NULL when X = Y, else X.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "arg0", + "nullability": "always" + } + ] + }, + { + "sql": "changes", + "kind": "scalar", + "doc": "Rows changed by the last statement.", + "deterministic": false, + "overloads": [ + { + "args": [], + "returns": "integer", + "nullability": "never" + } + ] + }, + { + "sql": "total_changes", + "kind": "scalar", + "doc": "Rows changed since connection open.", + "deterministic": false, + "overloads": [ + { + "args": [], + "returns": "integer", + "nullability": "never" + } + ] + }, + { + "sql": "last_insert_rowid", + "kind": "scalar", + "doc": "rowid of the most recent INSERT.", + "deterministic": false, + "overloads": [ + { + "args": [], + "returns": "integer", + "nullability": "never" + } + ] + }, + { + "sql": "sqlite_version", + "kind": "scalar", + "doc": "SQLite library version string.", + "deterministic": false, + "overloads": [ + { + "args": [], + "returns": "text", + "nullability": "never" + } + ] + }, + { + "sql": "sqlite_source_id", + "kind": "scalar", + "doc": "SQLite source check-in id.", + "deterministic": false, + "overloads": [ + { + "args": [], + "returns": "text", + "nullability": "never" + } + ] + } + ] +} diff --git a/src/types/sqlite/docs/lang_datefunc.json b/src/types/sqlite/docs/lang_datefunc.json new file mode 100644 index 00000000..706f6e76 --- /dev/null +++ b/src/types/sqlite/docs/lang_datefunc.json @@ -0,0 +1,175 @@ +{ + "page": "lang_datefunc.html", + "functions": [ + { + "sql": "date", + "kind": "scalar", + "doc": "YYYY-MM-DD for the given time value + modifiers.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "datetime" + }, + { + "type": "text", + "hint": "datetime-modifier", + "optional": true + } + ], + "variadic": true, + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "time", + "kind": "scalar", + "doc": "HH:MM:SS for the given time value + modifiers.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "datetime" + }, + { + "type": "text", + "hint": "datetime-modifier", + "optional": true + } + ], + "variadic": true, + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "datetime", + "kind": "scalar", + "doc": "YYYY-MM-DD HH:MM:SS for the given time value + modifiers.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "datetime" + }, + { + "type": "text", + "hint": "datetime-modifier", + "optional": true + } + ], + "variadic": true, + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "julianday", + "kind": "scalar", + "doc": "Julian day number (REAL).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "datetime" + }, + { + "type": "text", + "hint": "datetime-modifier", + "optional": true + } + ], + "variadic": true, + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "unixepoch", + "kind": "scalar", + "doc": "Unix timestamp (INTEGER; add 'subsec' for REAL).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "datetime" + }, + { + "type": "text", + "hint": "datetime-modifier", + "optional": true + } + ], + "variadic": true, + "returns": "integer", + "nullability": "on_error" + } + ] + }, + { + "sql": "strftime", + "kind": "scalar", + "doc": "Format a time value per the %-substitution string.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "strftime-format" + }, + { + "type": "any", + "hint": "datetime" + }, + { + "type": "text", + "hint": "datetime-modifier", + "optional": true + } + ], + "variadic": true, + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "timediff", + "kind": "scalar", + "doc": "Human-readable A \u2212 B duration (3.43+).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "any", + "hint": "datetime" + }, + { + "type": "any", + "hint": "datetime" + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + } + ] +} diff --git a/src/types/sqlite/docs/lang_expr.json b/src/types/sqlite/docs/lang_expr.json new file mode 100644 index 00000000..52de2439 --- /dev/null +++ b/src/types/sqlite/docs/lang_expr.json @@ -0,0 +1,652 @@ +{ + "page": "lang_expr.html", + "functions": [ + { + "sql": "=", + "kind": "binop", + "doc": "Equality (SQL three-valued).", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "propagates" + } + ] + }, + { + "sql": "<>", + "kind": "binop", + "doc": "Inequality (SQL three-valued).", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "propagates" + } + ] + }, + { + "sql": "<", + "kind": "binop", + "doc": "Less-than under SQLite's cross-type ordering.", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "propagates" + } + ] + }, + { + "sql": "<=", + "kind": "binop", + "doc": "Less-or-equal.", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "propagates" + } + ] + }, + { + "sql": ">", + "kind": "binop", + "doc": "Greater-than.", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "propagates" + } + ] + }, + { + "sql": ">=", + "kind": "binop", + "doc": "Greater-or-equal.", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "propagates" + } + ] + }, + { + "sql": "IS", + "kind": "binop", + "doc": "NULL-safe equality \u2014 never NULL.", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "never" + } + ] + }, + { + "sql": "IS NOT", + "kind": "binop", + "doc": "NULL-safe inequality \u2014 never NULL.", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "never" + } + ] + }, + { + "sql": "IS DISTINCT FROM", + "kind": "binop", + "doc": "Synonym for IS NOT.", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "never" + } + ] + }, + { + "sql": "IS NOT DISTINCT FROM", + "kind": "binop", + "doc": "Synonym for IS.", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "bool", + "nullability": "never" + } + ] + }, + { + "sql": "+", + "kind": "binop", + "doc": "Addition.", + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "integer" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "-", + "kind": "binop", + "doc": "Subtraction.", + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "integer" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "*", + "kind": "binop", + "doc": "Multiplication.", + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "integer" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "/", + "kind": "binop", + "doc": "Division \u2014 INTEGER/INTEGER truncates; \u00f70 \u2192 NULL.", + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "integer" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "%", + "kind": "binop", + "doc": "Remainder (integer semantics) \u2014 %0 \u2192 NULL.", + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "||", + "kind": "binop", + "doc": "String concatenation.", + "overloads": [ + { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "returns": "text", + "nullability": "propagates" + } + ] + }, + { + "sql": "&", + "kind": "binop", + "doc": "Bitwise AND (operands coerced to INTEGER).", + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + } + ] + }, + { + "sql": "|", + "kind": "binop", + "doc": "Bitwise OR.", + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + } + ] + }, + { + "sql": "<<", + "kind": "binop", + "doc": "Left shift.", + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + } + ] + }, + { + "sql": ">>", + "kind": "binop", + "doc": "Right shift.", + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + } + ] + }, + { + "sql": "->", + "kind": "binop", + "doc": "JSON subcomponent at path, as JSON text; NULL if absent.", + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "returns": "text", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "returns": "text", + "nullability": "on_error" + } + ] + }, + { + "sql": "->>", + "kind": "binop", + "doc": "JSON subcomponent at path, as SQL value; NULL if absent.", + "overloads": [ + { + "args": [ + { + "type": "text", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "returns": "any", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "blob", + "hint": "json" + }, + { + "type": "text", + "hint": "jsonpath" + } + ], + "returns": "any", + "nullability": "on_error" + } + ] + }, + { + "sql": "-", + "kind": "unaryop", + "doc": "Arithmetic negation.", + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "~", + "kind": "unaryop", + "doc": "Bitwise NOT (operand coerced to INTEGER).", + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + } + ] + } + ] +} diff --git a/src/types/sqlite/docs/lang_mathfunc.json b/src/types/sqlite/docs/lang_mathfunc.json new file mode 100644 index 00000000..6badf32b --- /dev/null +++ b/src/types/sqlite/docs/lang_mathfunc.json @@ -0,0 +1,866 @@ +{ + "page": "lang_mathfunc.html", + "functions": [ + { + "sql": "acos", + "kind": "scalar", + "doc": "Arccosine in radians.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "acosh", + "kind": "scalar", + "doc": "Inverse hyperbolic cosine.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "asin", + "kind": "scalar", + "doc": "Arcsine in radians.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "asinh", + "kind": "scalar", + "doc": "Inverse hyperbolic sine.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "atan", + "kind": "scalar", + "doc": "Arctangent in radians.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "atan2", + "kind": "scalar", + "doc": "atan2(Y, X) \u2014 arctangent of Y/X in radians.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "integer" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "atanh", + "kind": "scalar", + "doc": "Inverse hyperbolic tangent.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "ceil", + "kind": "scalar", + "doc": "Smallest integer \u2265 X.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "ceiling", + "kind": "scalar", + "doc": "Alias of ceil().", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "cos", + "kind": "scalar", + "doc": "Cosine of X (radians).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "cosh", + "kind": "scalar", + "doc": "Hyperbolic cosine.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "degrees", + "kind": "scalar", + "doc": "Radians \u2192 degrees.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "exp", + "kind": "scalar", + "doc": "e raised to X.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "floor", + "kind": "scalar", + "doc": "Largest integer \u2264 X.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "ln", + "kind": "scalar", + "doc": "Natural logarithm; NULL for X \u2264 0.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "log", + "kind": "scalar", + "doc": "log(X) base-10 log; log(B, X) base-B log. NULL for non-positive X.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "log10", + "kind": "scalar", + "doc": "Base-10 logarithm; NULL for X \u2264 0.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "log2", + "kind": "scalar", + "doc": "Base-2 logarithm; NULL for X \u2264 0.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "mod", + "kind": "scalar", + "doc": "mod(X, Y) \u2014 remainder of X/Y (C fmod semantics; result is REAL).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "integer" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "pi", + "kind": "scalar", + "doc": "\u03c0 as a REAL.", + "deterministic": true, + "overloads": [ + { + "args": [], + "returns": "real", + "nullability": "never" + } + ] + }, + { + "sql": "pow", + "kind": "scalar", + "doc": "pow(X, Y) \u2014 X raised to Y.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "integer" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "power", + "kind": "scalar", + "doc": "Alias of pow().", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "radians", + "kind": "scalar", + "doc": "Degrees \u2192 radians.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "sin", + "kind": "scalar", + "doc": "Sine of X (radians).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "sinh", + "kind": "scalar", + "doc": "Hyperbolic sine.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "sqrt", + "kind": "scalar", + "doc": "Square root; NULL for X < 0.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "on_error" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "on_error" + } + ] + }, + { + "sql": "tan", + "kind": "scalar", + "doc": "Tangent of X (radians).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "tanh", + "kind": "scalar", + "doc": "Hyperbolic tangent.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + }, + { + "sql": "trunc", + "kind": "scalar", + "doc": "Truncate toward zero.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "integer", + "nullability": "propagates" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "propagates" + } + ] + } + ] +} diff --git a/src/types/sqlite/docs/percentile.json b/src/types/sqlite/docs/percentile.json new file mode 100644 index 00000000..cb5547b8 --- /dev/null +++ b/src/types/sqlite/docs/percentile.json @@ -0,0 +1,133 @@ +{ + "page": "percentile.html", + "functions": [ + { + "sql": "median", + "kind": "aggregate", + "doc": "Median (percentile extension). Numeric inputs only.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + } + ], + "returns": "real", + "nullability": "always" + }, + { + "args": [ + { + "type": "real" + } + ], + "returns": "real", + "nullability": "always" + } + ] + }, + { + "sql": "percentile", + "kind": "aggregate", + "doc": "P-th percentile, P in 0..100 (percentile extension).", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "real", + "hint": "percent" + } + ], + "returns": "real", + "nullability": "always" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real", + "hint": "percent" + } + ], + "returns": "real", + "nullability": "always" + } + ] + }, + { + "sql": "percentile_cont", + "kind": "aggregate", + "doc": "Continuous percentile, fraction in 0..1.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "real", + "hint": "fraction" + } + ], + "returns": "real", + "nullability": "always" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real", + "hint": "fraction" + } + ], + "returns": "real", + "nullability": "always" + } + ] + }, + { + "sql": "percentile_disc", + "kind": "aggregate", + "doc": "Discrete percentile, fraction in 0..1.", + "deterministic": true, + "overloads": [ + { + "args": [ + { + "type": "integer" + }, + { + "type": "real", + "hint": "fraction" + } + ], + "returns": "real", + "nullability": "always" + }, + { + "args": [ + { + "type": "real" + }, + { + "type": "real", + "hint": "fraction" + } + ], + "returns": "real", + "nullability": "always" + } + ] + } + ] +} diff --git a/src/types/sqlite/emit.ts b/src/types/sqlite/emit.ts new file mode 100644 index 00000000..9ad6f53f --- /dev/null +++ b/src/types/sqlite/emit.ts @@ -0,0 +1,196 @@ +// SQLite dialect codegen entry — facts + type table + class chrome in, +// generated .ts files out via the unified emitter (../emission/emit.ts). +// All emission knowledge lives there; this file contributes DATA: the +// committed per-doc-page facts (docs/.json — schema and +// extraction prompt in docs/index.ts), the sqlite type table, and the +// per-class chrome (imports/statics/heritage). +// +// The emitted surface is derived from the facts by global rules — +// - method receivers = each overload's FIRST argument's domain +// ("any" ⇒ universal); args are in exact SQL call order; +// - names are camelCase(sql) for functions, symbol + PG-style +// alias for operators. +// The only remaining judgment is EXCLUSIONS below. Every claim is +// mechanically checked by signatures.verify.test.ts against the real +// engine; its completeness gate ensures every pragma_function_list +// entry is either defined in the facts or excluded here. +// +// Run: node --experimental-strip-types src/types/sqlite/emit.ts +// [--out-dir ] (codegen:check) + +import * as fs from "node:fs"; +import * as path from "node:path"; +import { pathToFileURL } from "node:url"; +import { DocPageSchema } from "./docs/index.ts"; +import { type EmitFn } from "../emission/facts.ts"; +import { + writeGeneratedTree, + chromeImportLines, + metaDeclareLines, + typnameStaticLines, + scanOverrideNames, + type ClassChrome, + type EmitConfig, + type TypeEntry, +} from "../emission/emit.ts"; + +const HEADER = + "// Auto-generated by src/types/sqlite/emit.ts from docs/*.json — do not edit.\n"; + +// --- facts: one JSON per vendored doc page -------------------------------- +// Loaded with fs (not import attributes — parser-neutral across node +// strip-types / swc / tsgo / tsdown) and zod-validated at import time: +// a malformed JSON fails loudly here, before any emission. + +const PAGES = [ + "lang_corefunc", + "lang_mathfunc", + "lang_datefunc", + "lang_aggfunc", + "percentile", + "json1", + "lang_expr", +] as const; + +export const SIGNATURES: EmitFn[] = PAGES.flatMap((page) => { + const raw = fs.readFileSync(path.join(import.meta.dirname, "docs", `${page}.json`), "utf8"); + return DocPageSchema.parse(JSON.parse(raw)).functions; +}); + +// Functions typegres refuses to surface — the completeness gate's +// whitelist: every pragma_function_list entry must be either defined +// in the facts or listed here. +export const EXCLUSIONS: string[] = [ + // Window functions — typegres has no OVER-clause modeling yet (PG + // doesn't either). Revisit with window support in the query builder. + "row_number", "rank", "dense_rank", "percent_rank", "cume_dist", "ntile", + "lag", "lead", "first_value", "last_value", "nth_value", + // FTS / rtree / geopoly — only meaningful on virtual tables, which + // typegres doesn't model. + "bm25", "fts3_tokenizer", "fts5", "fts5_get_locale", "fts5_insttoken", + "fts5_locale", "fts5_source_id", "highlight", "matchinfo", "offsets", + "optimize", "snippet", + "rtreecheck", "rtreedepth", "rtreenode", + "geopoly_area", "geopoly_bbox", "geopoly_blob", "geopoly_ccw", + "geopoly_contains_point", "geopoly_debug", "geopoly_group_bbox", + "geopoly_json", "geopoly_overlap", "geopoly_regular", "geopoly_svg", + "geopoly_within", "geopoly_xform", + "match", // MATCH operator function — only meaningful on FTS virtual tables + // Planner hints — no-ops for typing purposes; noise on the API. + "likelihood", "likely", "unlikely", + // Introspection / footguns. + "load_extension", // loads native code — must not be reachable from a query builder + "sqlite_compileoption_get", // build introspection + "sqlite_compileoption_used", // build introspection + "sqlite_offset", // low-level file-offset introspection + "sqlite_log", // error-log side effect, returns nothing useful + "subtype", // internal function-subtype plumbing + // CURRENT_* keywords aren't callable syntax — the datetime functions + // cover them (date('now'), time('now'), datetime('now')). + "current_date", "current_time", "current_timestamp", +]; + +// The sqlite type table. No `generic`/`element` entries (sqlite has +// no containers or pseudotypes), so the emitter's T-threading +// machinery stays dormant; receiver-following returns come from +// `returns: "arg0"` in the facts instead. +const TYPES: TypeEntry[] = [ + { + typname: "any", + className: "Any", + primitiveTsUnion: "number | string | boolean | Uint8Array", + }, + // primitiveTs here is emitter DATA (arg unions + collision routing); + // the runtime statics live in the hand-written overrides/.ts. + { typname: "integer", className: "Integer", primitiveTs: "number" }, + // integer and real share `number`; real outranks, so where twin + // overloads agree on the return, numbers (fractional included) + // dispatch through the value-preserving CAST(? AS REAL). + { typname: "real", className: "Real", primitiveTs: "number", losslessRank: 1 }, + { typname: "text", className: "Text", primitiveTs: "string" }, + { typname: "blob", className: "Blob", primitiveTsUnion: "Uint8Array" }, + { typname: "bool", className: "Bool", primitiveTs: "boolean" }, +]; + +const CONFIG: EmitConfig = { + typeTable: new Map(TYPES.map((t) => [t.typname, t])), + // Names owned by hand-written base members (bespoke typing on + // SqlValue/Any). + noMethod: new Set(["coalesce", "in"]), +}; + +// CAST/render target per class — the storage-class name, except bool: +// SQLite has no native bool, its storage class is INTEGER 0/1. +const CAST_TARGET: { [typname: string]: string } = { bool: "INTEGER" }; + +const PLACEMENT_DOC = `// Methods are placed by their receiver (first) argument's documented +// domain — runtime dispatch IS the type system for RPC callers +// (exoeval), so a value only carries the methods honest for its +// storage class. +// Every method: typed overload declarations over a runtime.match +// implementation (arg validation + primitive serialization + return +// class per matched overload — same dispatch model as PG).`; + +const chromeFor = (typname: string): ClassChrome => { + const lines: string[] = [HEADER.trimEnd()]; + + if (typname === "any") { + lines.push(`// The generated half of the SQLite root class (hand-written core — +// dialect metadata, isNull/isNotNull/in — extends this in +// ../overrides/any.ts). Carries ONLY the universal methods (receiver +// domain "any").`); + } else { + const cls = CONFIG.typeTable.get(typname)!.className; + lines.push(`// ${cls} — the ${typname} storage-class view: the __view brand +// (near-identical subclasses are otherwise structurally +// interchangeable, defeating nominal checks), [meta]/typname chrome, +// and the methods whose receiver domain is ${typname}. Hand-written +// behavior (deserialize, acceptsPrimitive) extends this in +// ../overrides/${typname}.ts.`); + } + lines.push(PLACEMENT_DOC); + + const parentImport = typname === "any" + ? 'import { SqlValue } from "../../sql-value";' + : 'import { Any } from "../overrides/any";'; + lines.push(...chromeImportLines(parentImport)); + + const cls = CONFIG.typeTable.get(typname)!.className; + lines.push(`export class ${cls} extends ${typname === "any" ? "SqlValue" : "Any"} {`); + + // Every concrete class (everything but the root) gets the brand + + // [meta] + typname chrome — same rule as PG. types.Cls refs: the + // barrel exports the hand-written override, so nullability + // transforms and runtime.pgType land on the full class. + if (typname !== "any") { + lines.push(` declare readonly __view: "${typname}";`); + lines.push(...metaDeclareLines(`types.${cls}`)); + lines.push(...typnameStaticLines(CAST_TARGET[typname] ?? typname.toUpperCase(), typname, true)); + lines.push(""); + } + + return { prologue: lines.join("\n"), epilogue: "}\n" }; +}; + +const main = (): void => { + const outDirFlag = process.argv.indexOf("--out-dir"); + const outDir = + outDirFlag >= 0 + ? path.resolve(process.argv[outDirFlag + 1]!) + : path.resolve(import.meta.dirname); + + writeGeneratedTree({ + generatedDir: path.join(outDir, "generated"), + barrelPath: path.join(import.meta.dirname, "index.ts"), + types: TYPES, + facts: SIGNATURES, + cfg: CONFIG, + chromeFor: (t) => chromeFor(t.typname), + overrides: scanOverrideNames(path.resolve(import.meta.dirname, "overrides")), + }); + console.log(`Generated ${TYPES.length} classes in ${path.join(outDir, "generated")}`); +}; + +if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { + main(); +} diff --git a/src/types/sqlite/functions.json b/src/types/sqlite/functions.json deleted file mode 100644 index 513b8352..00000000 --- a/src/types/sqlite/functions.json +++ /dev/null @@ -1,19931 +0,0 @@ -{ - "sqlite_version": "3.53.2", - "generated_at": "2026-07-07T21:32:06.908Z", - "function_count": 197, - "functions": { - "->": [ - { - "name": "->", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "integer", - "real" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "integer", - "text" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "integer", - "null" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "real", - "integer" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "real", - "real" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "real", - "text" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "real", - "blob" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "real", - "null" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "text", - "integer" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "text", - "real" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "text", - "text" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "text", - "blob" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "text", - "null" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "blob", - "real" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "blob", - "text" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "blob", - "null" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "null", - "integer" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "null", - "real" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "null", - "text" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "null", - "blob" - ], - "error": "near \"->\": syntax error" - }, - { - "args": [ - "null", - "null" - ], - "error": "near \"->\": syntax error" - } - ] - } - ], - "->>": [ - { - "name": "->>", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "integer", - "real" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "integer", - "text" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "integer", - "null" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "real", - "integer" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "real", - "real" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "real", - "text" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "real", - "blob" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "real", - "null" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "text", - "integer" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "text", - "real" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "text", - "text" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "text", - "blob" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "text", - "null" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "blob", - "real" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "blob", - "text" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "blob", - "null" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "null", - "integer" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "null", - "real" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "null", - "text" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "null", - "blob" - ], - "error": "near \"->>\": syntax error" - }, - { - "args": [ - "null", - "null" - ], - "error": "near \"->>\": syntax error" - } - ] - } - ], - "abs": [ - { - "name": "abs", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "real" - }, - { - "args": [ - "blob" - ], - "result": "real" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "acos": [ - { - "name": "acos", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "acosh": [ - { - "name": "acosh", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "asin": [ - { - "name": "asin", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "asinh": [ - { - "name": "asinh", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "atan": [ - { - "name": "atan", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "atan2": [ - { - "name": "atan2", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "real" - }, - { - "args": [ - "integer", - "real" - ], - "result": "real" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "atanh": [ - { - "name": "atanh", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "avg": [ - { - "name": "avg", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "real" - }, - { - "args": [ - "blob" - ], - "result": "real" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "bm25": [ - { - "name": "bm25", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "real" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "text" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "blob" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "null" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "integer", - "real" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "integer", - "text" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "integer", - "null" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "real", - "integer" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "real", - "real" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "real", - "text" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "real", - "blob" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "real", - "null" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "text", - "integer" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "text", - "real" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "text", - "text" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "text", - "blob" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "text", - "null" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "blob", - "real" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "blob", - "text" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "blob", - "null" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "null", - "integer" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "null", - "real" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "null", - "text" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "null", - "blob" - ], - "error": "unable to use function bm25 in the requested context" - }, - { - "args": [ - "null", - "null" - ], - "error": "unable to use function bm25 in the requested context" - } - ] - } - ], - "ceil": [ - { - "name": "ceil", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "ceiling": [ - { - "name": "ceiling", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "changes": [ - { - "name": "changes", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "integer" - } - ] - } - ], - "char": [ - { - "name": "char", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "text" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "text" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "text" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "text" - }, - { - "args": [ - "null", - "integer" - ], - "result": "text" - }, - { - "args": [ - "null", - "real" - ], - "result": "text" - }, - { - "args": [ - "null", - "text" - ], - "result": "text" - }, - { - "args": [ - "null", - "blob" - ], - "result": "text" - }, - { - "args": [ - "null", - "null" - ], - "result": "text" - } - ] - } - ], - "coalesce": [ - { - "name": "coalesce", - "type": "s", - "narg": -4, - "variadic": true, - "observations": [] - } - ], - "concat": [ - { - "name": "concat", - "type": "s", - "narg": -3, - "variadic": true, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "text" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "text" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "text" - }, - { - "args": [ - "null", - "integer" - ], - "result": "text" - }, - { - "args": [ - "null", - "real" - ], - "result": "text" - }, - { - "args": [ - "null", - "text" - ], - "result": "text" - }, - { - "args": [ - "null", - "blob" - ], - "result": "text" - }, - { - "args": [ - "null", - "null" - ], - "result": "text" - }, - { - "args": [ - "integer", - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "null", - "null", - "null" - ], - "result": "text" - } - ] - } - ], - "concat_ws": [ - { - "name": "concat_ws", - "type": "s", - "narg": -4, - "variadic": true, - "observations": [] - } - ], - "cos": [ - { - "name": "cos", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "cosh": [ - { - "name": "cosh", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "count": [ - { - "name": "count", - "type": "w", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "integer" - } - ] - }, - { - "name": "count", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null" - ], - "result": "integer" - } - ] - } - ], - "cume_dist": [ - { - "name": "cume_dist", - "type": "w", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "real" - } - ] - } - ], - "current_date": [ - { - "name": "current_date", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "error": "near \"(\": syntax error" - } - ] - } - ], - "current_time": [ - { - "name": "current_time", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "error": "near \"(\": syntax error" - } - ] - } - ], - "current_timestamp": [ - { - "name": "current_timestamp", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "error": "near \"(\": syntax error" - } - ] - } - ], - "date": [ - { - "name": "date", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "datetime": [ - { - "name": "datetime", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "degrees": [ - { - "name": "degrees", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "dense_rank": [ - { - "name": "dense_rank", - "type": "w", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "integer" - } - ] - } - ], - "exp": [ - { - "name": "exp", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "first_value": [ - { - "name": "first_value", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "floor": [ - { - "name": "floor", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "format": [ - { - "name": "format", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "text" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "text" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "text" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "fts3_tokenizer": [ - { - "name": "fts3_tokenizer", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "error": "unknown tokenizer: 1" - }, - { - "args": [ - "real" - ], - "error": "unknown tokenizer: 1.5" - }, - { - "args": [ - "text" - ], - "error": "unknown tokenizer: x" - }, - { - "args": [ - "blob" - ], - "error": "unknown tokenizer: \u0001" - }, - { - "args": [ - "null" - ], - "error": "unknown tokenizer: " - } - ] - }, - { - "name": "fts3_tokenizer", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "integer", - "real" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "integer", - "text" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "integer", - "null" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "real", - "integer" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "real", - "real" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "real", - "text" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "real", - "blob" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "real", - "null" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "text", - "integer" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "text", - "real" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "text", - "text" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "text", - "blob" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "text", - "null" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "blob", - "real" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "blob", - "text" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "blob", - "null" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "null", - "integer" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "null", - "real" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "null", - "text" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "null", - "blob" - ], - "error": "fts3tokenize disabled" - }, - { - "args": [ - "null", - "null" - ], - "error": "fts3tokenize disabled" - } - ] - } - ], - "fts5": [ - { - "name": "fts5", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "fts5_get_locale": [ - { - "name": "fts5_get_locale", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "real" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "text" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "blob" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "null" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "integer", - "real" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "integer", - "text" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "integer", - "null" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "real", - "integer" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "real", - "real" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "real", - "text" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "real", - "blob" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "real", - "null" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "text", - "integer" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "text", - "real" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "text", - "text" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "text", - "blob" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "text", - "null" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "blob", - "real" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "blob", - "text" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "blob", - "null" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "null", - "integer" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "null", - "real" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "null", - "text" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "null", - "blob" - ], - "error": "unable to use function fts5_get_locale in the requested context" - }, - { - "args": [ - "null", - "null" - ], - "error": "unable to use function fts5_get_locale in the requested context" - } - ] - } - ], - "fts5_insttoken": [ - { - "name": "fts5_insttoken", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "fts5_locale": [ - { - "name": "fts5_locale", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "real" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "text" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "null" - ], - "result": "blob" - }, - { - "args": [ - "real", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real", - "real" - ], - "result": "blob" - }, - { - "args": [ - "real", - "text" - ], - "result": "blob" - }, - { - "args": [ - "real", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "real", - "null" - ], - "result": "blob" - }, - { - "args": [ - "text", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "text", - "real" - ], - "result": "blob" - }, - { - "args": [ - "text", - "text" - ], - "result": "blob" - }, - { - "args": [ - "text", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "text", - "null" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "real" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "blob" - }, - { - "args": [ - "null", - "integer" - ], - "result": "text" - }, - { - "args": [ - "null", - "real" - ], - "result": "text" - }, - { - "args": [ - "null", - "text" - ], - "result": "text" - }, - { - "args": [ - "null", - "blob" - ], - "result": "text" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "fts5_source_id": [ - { - "name": "fts5_source_id", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "text" - } - ] - } - ], - "geopoly_area": [ - { - "name": "geopoly_area", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_bbox": [ - { - "name": "geopoly_bbox", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_blob": [ - { - "name": "geopoly_blob", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_ccw": [ - { - "name": "geopoly_ccw", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_contains_point": [ - { - "name": "geopoly_contains_point", - "type": "s", - "narg": 3, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_debug": [ - { - "name": "geopoly_debug", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_group_bbox": [ - { - "name": "geopoly_group_bbox", - "type": "a", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_json": [ - { - "name": "geopoly_json", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_overlap": [ - { - "name": "geopoly_overlap", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_regular": [ - { - "name": "geopoly_regular", - "type": "s", - "narg": 4, - "variadic": false, - "observations": [] - } - ], - "geopoly_svg": [ - { - "name": "geopoly_svg", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_within": [ - { - "name": "geopoly_within", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "geopoly_xform": [ - { - "name": "geopoly_xform", - "type": "s", - "narg": 7, - "variadic": false, - "observations": [] - } - ], - "glob": [ - { - "name": "glob", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "real" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "text" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real", - "real" - ], - "result": "integer" - }, - { - "args": [ - "real", - "text" - ], - "result": "integer" - }, - { - "args": [ - "real", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "text", - "real" - ], - "result": "integer" - }, - { - "args": [ - "text", - "text" - ], - "result": "integer" - }, - { - "args": [ - "text", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "real" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "null" - ], - "result": "integer" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "group_concat": [ - { - "name": "group_concat", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "group_concat", - "type": "w", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "text" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "text" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "text" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "hex": [ - { - "name": "hex", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "text" - } - ] - } - ], - "highlight": [ - { - "name": "highlight", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "real" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "text" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "blob" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "null" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "integer", - "real" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "integer", - "text" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "integer", - "null" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "real", - "integer" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "real", - "real" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "real", - "text" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "real", - "blob" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "real", - "null" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "text", - "integer" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "text", - "real" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "text", - "text" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "text", - "blob" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "text", - "null" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "blob", - "real" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "blob", - "text" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "blob", - "null" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "null", - "integer" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "null", - "real" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "null", - "text" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "null", - "blob" - ], - "error": "unable to use function highlight in the requested context" - }, - { - "args": [ - "null", - "null" - ], - "error": "unable to use function highlight in the requested context" - } - ] - } - ], - "if": [ - { - "name": "if", - "type": "s", - "narg": -4, - "variadic": true, - "observations": [] - } - ], - "ifnull": [ - { - "name": "ifnull", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "real" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "text" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "null" - ], - "result": "integer" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "real", - "text" - ], - "result": "real" - }, - { - "args": [ - "real", - "blob" - ], - "result": "real" - }, - { - "args": [ - "real", - "null" - ], - "result": "real" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "real" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "blob" - }, - { - "args": [ - "null", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "null", - "real" - ], - "result": "real" - }, - { - "args": [ - "null", - "text" - ], - "result": "text" - }, - { - "args": [ - "null", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "iif": [ - { - "name": "iif", - "type": "s", - "narg": -4, - "variadic": true, - "observations": [] - } - ], - "instr": [ - { - "name": "instr", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "real" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "text" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real", - "real" - ], - "result": "integer" - }, - { - "args": [ - "real", - "text" - ], - "result": "integer" - }, - { - "args": [ - "real", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "text", - "real" - ], - "result": "integer" - }, - { - "args": [ - "text", - "text" - ], - "result": "integer" - }, - { - "args": [ - "text", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "real" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "json": [ - { - "name": "json", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "json_array": [ - { - "name": "json_array", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "text" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "text" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "text" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "text" - }, - { - "args": [ - "null", - "integer" - ], - "result": "text" - }, - { - "args": [ - "null", - "real" - ], - "result": "text" - }, - { - "args": [ - "null", - "text" - ], - "result": "text" - }, - { - "args": [ - "null", - "blob" - ], - "result": "text" - }, - { - "args": [ - "null", - "null" - ], - "result": "text" - } - ] - } - ], - "json_array_insert": [ - { - "name": "json_array_insert", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "real" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "text" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "null" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "integer" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "real" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "text" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "blob" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "null" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "integer" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "real" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "text" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "blob" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "null" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "real" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "text" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "null" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "integer" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "real" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "text" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "blob" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "null" - ], - "error": "json_array_insert() needs an odd number of arguments" - } - ] - } - ], - "json_array_length": [ - { - "name": "json_array_length", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "json_array_length", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "integer", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "integer", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "real", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "real", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "real", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "real" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "blob" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "null" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "blob", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "blob", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "json_error_position": [ - { - "name": "json_error_position", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "json_extract": [ - { - "name": "json_extract", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "integer", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "integer", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "real", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "real", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "real", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "real" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "blob" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "null" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "blob", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "blob", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "json_group_array": [ - { - "name": "json_group_array", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "text" - } - ] - } - ], - "json_group_object": [ - { - "name": "json_group_object", - "type": "w", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "text" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "text" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "text" - }, - { - "args": [ - "null", - "integer" - ], - "result": "text" - }, - { - "args": [ - "null", - "real" - ], - "result": "text" - }, - { - "args": [ - "null", - "text" - ], - "result": "text" - }, - { - "args": [ - "null", - "blob" - ], - "result": "text" - }, - { - "args": [ - "null", - "null" - ], - "result": "text" - } - ] - } - ], - "json_insert": [ - { - "name": "json_insert", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "real" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "text" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "null" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "integer" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "real" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "text" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "blob" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "null" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "integer" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "real" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "text" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "blob" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "null" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "real" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "text" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "null" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "integer" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "real" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "text" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "blob" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "null" - ], - "error": "json_insert() needs an odd number of arguments" - } - ] - } - ], - "json_object": [ - { - "name": "json_object", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "error": "json_object() requires an even number of arguments" - }, - { - "args": [ - "real" - ], - "error": "json_object() requires an even number of arguments" - }, - { - "args": [ - "text" - ], - "error": "json_object() requires an even number of arguments" - }, - { - "args": [ - "blob" - ], - "error": "json_object() requires an even number of arguments" - }, - { - "args": [ - "null" - ], - "error": "json_object() requires an even number of arguments" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "integer", - "real" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "integer", - "text" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "integer", - "null" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "real", - "integer" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "real", - "real" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "real", - "text" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "real", - "blob" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "real", - "null" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "blob", - "real" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "blob", - "text" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "blob", - "null" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "null", - "integer" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "null", - "real" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "null", - "text" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "null", - "blob" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "null", - "null" - ], - "error": "json_object() labels must be TEXT" - } - ] - } - ], - "json_patch": [ - { - "name": "json_patch", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "real" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "blob" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "null" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "json_pretty": [ - { - "name": "json_pretty", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "json_pretty", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "text" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "text" - }, - { - "args": [ - "text", - "integer" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "real" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "blob" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "null" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "text" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "json_quote": [ - { - "name": "json_quote", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "text" - } - ] - } - ], - "json_remove": [ - { - "name": "json_remove", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "integer", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "integer", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "real", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "real", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "real", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "real" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "blob" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "null" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "blob", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "blob", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "json_replace": [ - { - "name": "json_replace", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "real" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "text" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "null" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "real", - "integer" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "real", - "real" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "real", - "text" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "real", - "blob" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "real", - "null" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "text", - "integer" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "text", - "real" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "text", - "text" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "text", - "blob" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "text", - "null" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "real" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "text" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "null" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "null", - "integer" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "null", - "real" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "null", - "text" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "null", - "blob" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "null", - "null" - ], - "error": "json_replace() needs an odd number of arguments" - } - ] - } - ], - "json_set": [ - { - "name": "json_set", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "real" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "text" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "null" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "real", - "integer" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "real", - "real" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "real", - "text" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "real", - "blob" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "real", - "null" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "text", - "integer" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "text", - "real" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "text", - "text" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "text", - "blob" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "text", - "null" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "real" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "text" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "null" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "null", - "integer" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "null", - "real" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "null", - "text" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "null", - "blob" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "null", - "null" - ], - "error": "json_set() needs an odd number of arguments" - } - ] - } - ], - "json_type": [ - { - "name": "json_type", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "json_type", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "integer", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "integer", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "real", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "real", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "real", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "real" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "blob" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "null" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "blob", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "blob", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "json_valid": [ - { - "name": "json_valid", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "json_valid", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "real" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "text" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "integer", - "null" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "real", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real", - "real" - ], - "result": "integer" - }, - { - "args": [ - "real", - "text" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "real", - "blob" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "real", - "null" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "text", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "text", - "real" - ], - "result": "integer" - }, - { - "args": [ - "text", - "text" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "text", - "blob" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "text", - "null" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "real" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "text" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "blob", - "null" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "null", - "blob" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - }, - { - "args": [ - "null", - "null" - ], - "error": "FLAGS parameter to json_valid() must be between 1 and 15" - } - ] - } - ], - "jsonb": [ - { - "name": "jsonb", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real" - ], - "result": "blob" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "jsonb_array": [ - { - "name": "jsonb_array", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real" - ], - "result": "blob" - }, - { - "args": [ - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "real" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "text" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "null" - ], - "result": "blob" - }, - { - "args": [ - "real", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real", - "real" - ], - "result": "blob" - }, - { - "args": [ - "real", - "text" - ], - "result": "blob" - }, - { - "args": [ - "real", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "real", - "null" - ], - "result": "blob" - }, - { - "args": [ - "text", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "text", - "real" - ], - "result": "blob" - }, - { - "args": [ - "text", - "text" - ], - "result": "blob" - }, - { - "args": [ - "text", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "text", - "null" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "real" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "blob" - }, - { - "args": [ - "null", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "null", - "real" - ], - "result": "blob" - }, - { - "args": [ - "null", - "text" - ], - "result": "blob" - }, - { - "args": [ - "null", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null", - "null" - ], - "result": "blob" - } - ] - } - ], - "jsonb_array_insert": [ - { - "name": "jsonb_array_insert", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real" - ], - "result": "blob" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "real" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "text" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "null" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "integer" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "real" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "text" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "blob" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "null" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "integer" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "real" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "text" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "blob" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "null" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "real" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "text" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "null" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "integer" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "real" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "text" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "blob" - ], - "error": "json_array_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "null" - ], - "error": "json_array_insert() needs an odd number of arguments" - } - ] - } - ], - "jsonb_extract": [ - { - "name": "jsonb_extract", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "integer", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "integer", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "real", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "real", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "real", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "real" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "blob" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "null" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "blob", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "blob", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "jsonb_group_array": [ - { - "name": "jsonb_group_array", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real" - ], - "result": "blob" - }, - { - "args": [ - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "blob" - } - ] - } - ], - "jsonb_group_object": [ - { - "name": "jsonb_group_object", - "type": "w", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "real" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "text" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "null" - ], - "result": "blob" - }, - { - "args": [ - "real", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real", - "real" - ], - "result": "blob" - }, - { - "args": [ - "real", - "text" - ], - "result": "blob" - }, - { - "args": [ - "real", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "real", - "null" - ], - "result": "blob" - }, - { - "args": [ - "text", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "text", - "real" - ], - "result": "blob" - }, - { - "args": [ - "text", - "text" - ], - "result": "blob" - }, - { - "args": [ - "text", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "text", - "null" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "real" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "blob" - }, - { - "args": [ - "null", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "null", - "real" - ], - "result": "blob" - }, - { - "args": [ - "null", - "text" - ], - "result": "blob" - }, - { - "args": [ - "null", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null", - "null" - ], - "result": "blob" - } - ] - } - ], - "jsonb_insert": [ - { - "name": "jsonb_insert", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real" - ], - "result": "blob" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "real" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "text" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "null" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "integer" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "real" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "text" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "blob" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "real", - "null" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "integer" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "real" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "text" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "blob" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "text", - "null" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "real" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "text" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "null" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "integer" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "real" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "text" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "blob" - ], - "error": "json_insert() needs an odd number of arguments" - }, - { - "args": [ - "null", - "null" - ], - "error": "json_insert() needs an odd number of arguments" - } - ] - } - ], - "jsonb_object": [ - { - "name": "jsonb_object", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "error": "json_object() requires an even number of arguments" - }, - { - "args": [ - "real" - ], - "error": "json_object() requires an even number of arguments" - }, - { - "args": [ - "text" - ], - "error": "json_object() requires an even number of arguments" - }, - { - "args": [ - "blob" - ], - "error": "json_object() requires an even number of arguments" - }, - { - "args": [ - "null" - ], - "error": "json_object() requires an even number of arguments" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "integer", - "real" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "integer", - "text" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "integer", - "null" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "real", - "integer" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "real", - "real" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "real", - "text" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "real", - "blob" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "real", - "null" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "text", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "text", - "real" - ], - "result": "blob" - }, - { - "args": [ - "text", - "text" - ], - "result": "blob" - }, - { - "args": [ - "text", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "text", - "null" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "blob", - "real" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "blob", - "text" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "blob", - "null" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "null", - "integer" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "null", - "real" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "null", - "text" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "null", - "blob" - ], - "error": "json_object() labels must be TEXT" - }, - { - "args": [ - "null", - "null" - ], - "error": "json_object() labels must be TEXT" - } - ] - } - ], - "jsonb_patch": [ - { - "name": "jsonb_patch", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "real" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real", - "real" - ], - "result": "blob" - }, - { - "args": [ - "real", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "real", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "real" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "blob" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "null" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "real" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "jsonb_remove": [ - { - "name": "jsonb_remove", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real" - ], - "result": "blob" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "integer", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "integer", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "real", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "real", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "real", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "real" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "blob" - ], - "error": "malformed JSON" - }, - { - "args": [ - "text", - "null" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "bad JSON path: '1'" - }, - { - "args": [ - "blob", - "real" - ], - "error": "bad JSON path: '1.5'" - }, - { - "args": [ - "blob", - "text" - ], - "error": "bad JSON path: 'x'" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "bad JSON path: '\u0001'" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "jsonb_replace": [ - { - "name": "jsonb_replace", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real" - ], - "result": "blob" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "real" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "text" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "null" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "real", - "integer" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "real", - "real" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "real", - "text" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "real", - "blob" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "real", - "null" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "text", - "integer" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "text", - "real" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "text", - "text" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "text", - "blob" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "text", - "null" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "real" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "text" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "null" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "null", - "integer" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "null", - "real" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "null", - "text" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "null", - "blob" - ], - "error": "json_replace() needs an odd number of arguments" - }, - { - "args": [ - "null", - "null" - ], - "error": "json_replace() needs an odd number of arguments" - } - ] - } - ], - "jsonb_set": [ - { - "name": "jsonb_set", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real" - ], - "result": "blob" - }, - { - "args": [ - "text" - ], - "error": "malformed JSON" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "real" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "text" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "integer", - "null" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "real", - "integer" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "real", - "real" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "real", - "text" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "real", - "blob" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "real", - "null" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "text", - "integer" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "text", - "real" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "text", - "text" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "text", - "blob" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "text", - "null" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "real" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "text" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "blob", - "null" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "null", - "integer" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "null", - "real" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "null", - "text" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "null", - "blob" - ], - "error": "json_set() needs an odd number of arguments" - }, - { - "args": [ - "null", - "null" - ], - "error": "json_set() needs an odd number of arguments" - } - ] - } - ], - "julianday": [ - { - "name": "julianday", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "lag": [ - { - "name": "lag", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "lag", - "type": "w", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "real" - }, - { - "args": [ - "real", - "blob" - ], - "result": "real" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - }, - { - "name": "lag", - "type": "w", - "narg": 3, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real", - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "text", - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null", - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "last_insert_rowid": [ - { - "name": "last_insert_rowid", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "integer" - } - ] - } - ], - "last_value": [ - { - "name": "last_value", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "lead": [ - { - "name": "lead", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "lead", - "type": "w", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "real" - }, - { - "args": [ - "real", - "blob" - ], - "result": "real" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - }, - { - "name": "lead", - "type": "w", - "narg": 3, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real", - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "text", - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null", - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "length": [ - { - "name": "length", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "like": [ - { - "name": "like", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "real" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "text" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real", - "real" - ], - "result": "integer" - }, - { - "args": [ - "real", - "text" - ], - "result": "integer" - }, - { - "args": [ - "real", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "text", - "real" - ], - "result": "integer" - }, - { - "args": [ - "text", - "text" - ], - "result": "integer" - }, - { - "args": [ - "text", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "real" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "null" - ], - "result": "integer" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - }, - { - "name": "like", - "type": "s", - "narg": 3, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real", - "real", - "real" - ], - "error": "ESCAPE expression must be a single character" - }, - { - "args": [ - "text", - "text", - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "blob", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null", - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "likelihood": [ - { - "name": "likelihood", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "integer", - "real" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "integer", - "text" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "integer", - "null" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "real", - "integer" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "real", - "real" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "real", - "text" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "real", - "blob" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "real", - "null" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "text", - "integer" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "text", - "real" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "text", - "text" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "text", - "blob" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "text", - "null" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "real" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "text" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "null" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "null", - "integer" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "null", - "real" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "null", - "text" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "null", - "blob" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - }, - { - "args": [ - "null", - "null" - ], - "error": "second argument to likelihood() must be a constant between 0.0 and 1.0" - } - ] - } - ], - "likely": [ - { - "name": "likely", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "ln": [ - { - "name": "ln", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "load_extension": [ - { - "name": "load_extension", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "error": "not authorized" - }, - { - "args": [ - "real" - ], - "error": "not authorized" - }, - { - "args": [ - "text" - ], - "error": "not authorized" - }, - { - "args": [ - "blob" - ], - "error": "not authorized" - }, - { - "args": [ - "null" - ], - "error": "not authorized" - } - ] - }, - { - "name": "load_extension", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "error": "not authorized" - }, - { - "args": [ - "integer", - "real" - ], - "error": "not authorized" - }, - { - "args": [ - "integer", - "text" - ], - "error": "not authorized" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "not authorized" - }, - { - "args": [ - "integer", - "null" - ], - "error": "not authorized" - }, - { - "args": [ - "real", - "integer" - ], - "error": "not authorized" - }, - { - "args": [ - "real", - "real" - ], - "error": "not authorized" - }, - { - "args": [ - "real", - "text" - ], - "error": "not authorized" - }, - { - "args": [ - "real", - "blob" - ], - "error": "not authorized" - }, - { - "args": [ - "real", - "null" - ], - "error": "not authorized" - }, - { - "args": [ - "text", - "integer" - ], - "error": "not authorized" - }, - { - "args": [ - "text", - "real" - ], - "error": "not authorized" - }, - { - "args": [ - "text", - "text" - ], - "error": "not authorized" - }, - { - "args": [ - "text", - "blob" - ], - "error": "not authorized" - }, - { - "args": [ - "text", - "null" - ], - "error": "not authorized" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "not authorized" - }, - { - "args": [ - "blob", - "real" - ], - "error": "not authorized" - }, - { - "args": [ - "blob", - "text" - ], - "error": "not authorized" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "not authorized" - }, - { - "args": [ - "blob", - "null" - ], - "error": "not authorized" - }, - { - "args": [ - "null", - "integer" - ], - "error": "not authorized" - }, - { - "args": [ - "null", - "real" - ], - "error": "not authorized" - }, - { - "args": [ - "null", - "text" - ], - "error": "not authorized" - }, - { - "args": [ - "null", - "blob" - ], - "error": "not authorized" - }, - { - "args": [ - "null", - "null" - ], - "error": "not authorized" - } - ] - } - ], - "log": [ - { - "name": "log", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "log", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "log10": [ - { - "name": "log10", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "log2": [ - { - "name": "log2", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "lower": [ - { - "name": "lower", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "ltrim": [ - { - "name": "ltrim", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "ltrim", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "match": [ - { - "name": "match", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "integer", - "real" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "integer", - "text" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "integer", - "null" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "real", - "integer" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "real", - "real" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "real", - "text" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "real", - "blob" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "real", - "null" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "text", - "integer" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "text", - "real" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "text", - "text" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "text", - "blob" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "text", - "null" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "blob", - "real" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "blob", - "text" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "blob", - "null" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "null", - "integer" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "null", - "real" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "null", - "text" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "null", - "blob" - ], - "error": "unable to use function MATCH in the requested context" - }, - { - "args": [ - "null", - "null" - ], - "error": "unable to use function MATCH in the requested context" - } - ] - } - ], - "matchinfo": [ - { - "name": "matchinfo", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "real" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "text" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "blob" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "null" - ], - "error": "unable to use function matchinfo in the requested context" - } - ] - }, - { - "name": "matchinfo", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "integer", - "real" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "integer", - "text" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "integer", - "null" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "real", - "integer" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "real", - "real" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "real", - "text" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "real", - "blob" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "real", - "null" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "text", - "integer" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "text", - "real" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "text", - "text" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "text", - "blob" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "text", - "null" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "blob", - "real" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "blob", - "text" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "blob", - "null" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "null", - "integer" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "null", - "real" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "null", - "text" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "null", - "blob" - ], - "error": "unable to use function matchinfo in the requested context" - }, - { - "args": [ - "null", - "null" - ], - "error": "unable to use function matchinfo in the requested context" - } - ] - } - ], - "max": [ - { - "name": "max", - "type": "s", - "narg": -3, - "variadic": true, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "real" - ], - "result": "real" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "real" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real", - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "text", - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null", - "null", - "null" - ], - "result": "null" - } - ] - }, - { - "name": "max", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "median": [ - { - "name": "median", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "error": "input to median() is not numeric" - }, - { - "args": [ - "blob" - ], - "error": "input to median() is not numeric" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "min": [ - { - "name": "min", - "type": "s", - "narg": -3, - "variadic": true, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "real" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "text" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "real", - "text" - ], - "result": "real" - }, - { - "args": [ - "real", - "blob" - ], - "result": "real" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "text", - "real" - ], - "result": "real" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "blob", - "real" - ], - "result": "real" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real", - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "text", - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null", - "null", - "null" - ], - "result": "null" - } - ] - }, - { - "name": "min", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "mod": [ - { - "name": "mod", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "real" - }, - { - "args": [ - "integer", - "real" - ], - "result": "real" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "nth_value": [ - { - "name": "nth_value", - "type": "w", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "real" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "integer", - "text" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "integer", - "null" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "real", - "text" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "real", - "blob" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "real", - "null" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "text", - "text" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "text", - "blob" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "text", - "null" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "real" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "blob", - "text" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "blob", - "null" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "null", - "text" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "null", - "blob" - ], - "error": "second argument to nth_value must be a positive integer" - }, - { - "args": [ - "null", - "null" - ], - "error": "second argument to nth_value must be a positive integer" - } - ] - } - ], - "ntile": [ - { - "name": "ntile", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "error": "argument of ntile must be a positive integer" - }, - { - "args": [ - "blob" - ], - "error": "argument of ntile must be a positive integer" - }, - { - "args": [ - "null" - ], - "error": "argument of ntile must be a positive integer" - } - ] - } - ], - "nullif": [ - { - "name": "nullif", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "text" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "integer" - }, - { - "args": [ - "integer", - "null" - ], - "result": "integer" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "real" - }, - { - "args": [ - "real", - "blob" - ], - "result": "real" - }, - { - "args": [ - "real", - "null" - ], - "result": "real" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "real" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "blob" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "octet_length": [ - { - "name": "octet_length", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "offsets": [ - { - "name": "offsets", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "error": "unable to use function offsets in the requested context" - }, - { - "args": [ - "real" - ], - "error": "unable to use function offsets in the requested context" - }, - { - "args": [ - "text" - ], - "error": "unable to use function offsets in the requested context" - }, - { - "args": [ - "blob" - ], - "error": "unable to use function offsets in the requested context" - }, - { - "args": [ - "null" - ], - "error": "unable to use function offsets in the requested context" - } - ] - } - ], - "optimize": [ - { - "name": "optimize", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "error": "unable to use function optimize in the requested context" - }, - { - "args": [ - "real" - ], - "error": "unable to use function optimize in the requested context" - }, - { - "args": [ - "text" - ], - "error": "unable to use function optimize in the requested context" - }, - { - "args": [ - "blob" - ], - "error": "unable to use function optimize in the requested context" - }, - { - "args": [ - "null" - ], - "error": "unable to use function optimize in the requested context" - } - ] - } - ], - "percent_rank": [ - { - "name": "percent_rank", - "type": "w", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "real" - } - ] - } - ], - "percentile": [ - { - "name": "percentile", - "type": "w", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "real" - }, - { - "args": [ - "integer", - "real" - ], - "result": "real" - }, - { - "args": [ - "integer", - "text" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "integer", - "null" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "real", - "text" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "real", - "blob" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "real", - "null" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "text", - "integer" - ], - "error": "input to percentile() is not numeric" - }, - { - "args": [ - "text", - "real" - ], - "error": "input to percentile() is not numeric" - }, - { - "args": [ - "text", - "text" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "text", - "blob" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "text", - "null" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "input to percentile() is not numeric" - }, - { - "args": [ - "blob", - "real" - ], - "error": "input to percentile() is not numeric" - }, - { - "args": [ - "blob", - "text" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "blob", - "null" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "null", - "blob" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - }, - { - "args": [ - "null", - "null" - ], - "error": "the fraction argument to percentile() is not between 0.0 and 100.0" - } - ] - } - ], - "percentile_cont": [ - { - "name": "percentile_cont", - "type": "w", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "real" - }, - { - "args": [ - "integer", - "real" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "integer", - "text" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "integer", - "null" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "real", - "text" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "real", - "blob" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "real", - "null" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "text", - "integer" - ], - "error": "input to percentile_cont() is not numeric" - }, - { - "args": [ - "text", - "real" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "text", - "text" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "text", - "blob" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "text", - "null" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "input to percentile_cont() is not numeric" - }, - { - "args": [ - "blob", - "real" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "text" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "null" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "null", - "text" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "null", - "blob" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - }, - { - "args": [ - "null", - "null" - ], - "error": "the fraction argument to percentile_cont() is not between 0.0 and 1.0" - } - ] - } - ], - "percentile_disc": [ - { - "name": "percentile_disc", - "type": "w", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "real" - }, - { - "args": [ - "integer", - "real" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "integer", - "text" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "integer", - "null" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "real", - "text" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "real", - "blob" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "real", - "null" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "text", - "integer" - ], - "error": "input to percentile_disc() is not numeric" - }, - { - "args": [ - "text", - "real" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "text", - "text" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "text", - "blob" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "text", - "null" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "input to percentile_disc() is not numeric" - }, - { - "args": [ - "blob", - "real" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "text" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "blob", - "null" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "null", - "text" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "null", - "blob" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - }, - { - "args": [ - "null", - "null" - ], - "error": "the fraction argument to percentile_disc() is not between 0.0 and 1.0" - } - ] - } - ], - "pi": [ - { - "name": "pi", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "real" - } - ] - } - ], - "pow": [ - { - "name": "pow", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "real" - }, - { - "args": [ - "integer", - "real" - ], - "result": "real" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "power": [ - { - "name": "power", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "real" - }, - { - "args": [ - "integer", - "real" - ], - "result": "real" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "printf": [ - { - "name": "printf", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "text" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "text" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "text" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "quote": [ - { - "name": "quote", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "text" - } - ] - } - ], - "radians": [ - { - "name": "radians", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "random": [ - { - "name": "random", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "integer" - } - ] - } - ], - "randomblob": [ - { - "name": "randomblob", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real" - ], - "result": "blob" - }, - { - "args": [ - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "blob" - } - ] - } - ], - "rank": [ - { - "name": "rank", - "type": "w", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "integer" - } - ] - } - ], - "replace": [ - { - "name": "replace", - "type": "s", - "narg": 3, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "null", - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "round": [ - { - "name": "round", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "real" - }, - { - "args": [ - "blob" - ], - "result": "real" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "round", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "real" - }, - { - "args": [ - "integer", - "real" - ], - "result": "real" - }, - { - "args": [ - "integer", - "text" - ], - "result": "real" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "real" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "real" - }, - { - "args": [ - "real", - "real" - ], - "result": "real" - }, - { - "args": [ - "real", - "text" - ], - "result": "real" - }, - { - "args": [ - "real", - "blob" - ], - "result": "real" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "real" - }, - { - "args": [ - "text", - "real" - ], - "result": "real" - }, - { - "args": [ - "text", - "text" - ], - "result": "real" - }, - { - "args": [ - "text", - "blob" - ], - "result": "real" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "real" - }, - { - "args": [ - "blob", - "real" - ], - "result": "real" - }, - { - "args": [ - "blob", - "text" - ], - "result": "real" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "real" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "row_number": [ - { - "name": "row_number", - "type": "w", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "integer" - } - ] - } - ], - "rtreecheck": [ - { - "name": "rtreecheck", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "error": "SQL logic error" - }, - { - "args": [ - "real" - ], - "error": "SQL logic error" - }, - { - "args": [ - "text" - ], - "error": "SQL logic error" - }, - { - "args": [ - "blob" - ], - "error": "SQL logic error" - }, - { - "args": [ - "null" - ], - "error": "SQL logic error" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "SQL logic error" - }, - { - "args": [ - "integer", - "real" - ], - "error": "SQL logic error" - }, - { - "args": [ - "integer", - "text" - ], - "error": "SQL logic error" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "SQL logic error" - }, - { - "args": [ - "integer", - "null" - ], - "error": "SQL logic error" - }, - { - "args": [ - "real", - "integer" - ], - "error": "SQL logic error" - }, - { - "args": [ - "real", - "real" - ], - "error": "SQL logic error" - }, - { - "args": [ - "real", - "text" - ], - "error": "SQL logic error" - }, - { - "args": [ - "real", - "blob" - ], - "error": "SQL logic error" - }, - { - "args": [ - "real", - "null" - ], - "error": "SQL logic error" - }, - { - "args": [ - "text", - "integer" - ], - "error": "SQL logic error" - }, - { - "args": [ - "text", - "real" - ], - "error": "SQL logic error" - }, - { - "args": [ - "text", - "text" - ], - "error": "SQL logic error" - }, - { - "args": [ - "text", - "blob" - ], - "error": "SQL logic error" - }, - { - "args": [ - "text", - "null" - ], - "error": "SQL logic error" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "SQL logic error" - }, - { - "args": [ - "blob", - "real" - ], - "error": "SQL logic error" - }, - { - "args": [ - "blob", - "text" - ], - "error": "SQL logic error" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "SQL logic error" - }, - { - "args": [ - "blob", - "null" - ], - "error": "SQL logic error" - }, - { - "args": [ - "null", - "integer" - ], - "error": "SQL logic error" - }, - { - "args": [ - "null", - "real" - ], - "error": "SQL logic error" - }, - { - "args": [ - "null", - "text" - ], - "error": "SQL logic error" - }, - { - "args": [ - "null", - "blob" - ], - "error": "SQL logic error" - }, - { - "args": [ - "null", - "null" - ], - "error": "SQL logic error" - } - ] - } - ], - "rtreedepth": [ - { - "name": "rtreedepth", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "error": "Invalid argument to rtreedepth()" - }, - { - "args": [ - "real" - ], - "error": "Invalid argument to rtreedepth()" - }, - { - "args": [ - "text" - ], - "error": "Invalid argument to rtreedepth()" - }, - { - "args": [ - "blob" - ], - "error": "Invalid argument to rtreedepth()" - }, - { - "args": [ - "null" - ], - "error": "Invalid argument to rtreedepth()" - } - ] - } - ], - "rtreenode": [ - { - "name": "rtreenode", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "rtrim": [ - { - "name": "rtrim", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "rtrim", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "sign": [ - { - "name": "sign", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "sin": [ - { - "name": "sin", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "sinh": [ - { - "name": "sinh", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "snippet": [ - { - "name": "snippet", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "real" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "text" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "blob" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "null" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "integer", - "integer" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "integer", - "real" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "integer", - "text" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "integer", - "blob" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "integer", - "null" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "real", - "integer" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "real", - "real" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "real", - "text" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "real", - "blob" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "real", - "null" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "text", - "integer" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "text", - "real" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "text", - "text" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "text", - "blob" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "text", - "null" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "blob", - "integer" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "blob", - "real" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "blob", - "text" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "blob", - "blob" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "blob", - "null" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "null", - "integer" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "null", - "real" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "null", - "text" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "null", - "blob" - ], - "error": "unable to use function snippet in the requested context" - }, - { - "args": [ - "null", - "null" - ], - "error": "unable to use function snippet in the requested context" - } - ] - } - ], - "soundex": [ - { - "name": "soundex", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "text" - } - ] - } - ], - "sqlite_compileoption_get": [ - { - "name": "sqlite_compileoption_get", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "text" - } - ] - } - ], - "sqlite_compileoption_used": [ - { - "name": "sqlite_compileoption_used", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "sqlite_log": [ - { - "name": "sqlite_log", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "sqlite_source_id": [ - { - "name": "sqlite_source_id", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "text" - } - ] - } - ], - "sqlite_version": [ - { - "name": "sqlite_version", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "text" - } - ] - } - ], - "sqrt": [ - { - "name": "sqrt", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "strftime": [ - { - "name": "strftime", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "string_agg": [ - { - "name": "string_agg", - "type": "w", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "text" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "text" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "text" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "text" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "substr": [ - { - "name": "substr", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "real" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - }, - { - "name": "substr", - "type": "s", - "narg": 3, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null", - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "substring": [ - { - "name": "substring", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "real" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - }, - { - "name": "substring", - "type": "s", - "narg": 3, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null", - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "subtype": [ - { - "name": "subtype", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null" - ], - "result": "integer" - } - ] - } - ], - "sum": [ - { - "name": "sum", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "real" - }, - { - "args": [ - "blob" - ], - "result": "real" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "tan": [ - { - "name": "tan", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "tanh": [ - { - "name": "tanh", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "time": [ - { - "name": "time", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "timediff": [ - { - "name": "timediff", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "total": [ - { - "name": "total", - "type": "w", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "real" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "real" - }, - { - "args": [ - "blob" - ], - "result": "real" - }, - { - "args": [ - "null" - ], - "result": "real" - } - ] - } - ], - "total_changes": [ - { - "name": "total_changes", - "type": "s", - "narg": 0, - "variadic": false, - "observations": [ - { - "args": [], - "result": "integer" - } - ] - } - ], - "trim": [ - { - "name": "trim", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "trim", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "text" - }, - { - "args": [ - "integer", - "real" - ], - "result": "text" - }, - { - "args": [ - "integer", - "text" - ], - "result": "text" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "text" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "text" - }, - { - "args": [ - "real", - "real" - ], - "result": "text" - }, - { - "args": [ - "real", - "text" - ], - "result": "text" - }, - { - "args": [ - "real", - "blob" - ], - "result": "text" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "text" - }, - { - "args": [ - "text", - "real" - ], - "result": "text" - }, - { - "args": [ - "text", - "text" - ], - "result": "text" - }, - { - "args": [ - "text", - "blob" - ], - "result": "text" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "text" - }, - { - "args": [ - "blob", - "real" - ], - "result": "text" - }, - { - "args": [ - "blob", - "text" - ], - "result": "text" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "text" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "trunc": [ - { - "name": "trunc", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "typeof": [ - { - "name": "typeof", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "text" - } - ] - } - ], - "unhex": [ - { - "name": "unhex", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "null" - }, - { - "args": [ - "real" - ], - "result": "null" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - }, - { - "name": "unhex", - "type": "s", - "narg": 2, - "variadic": false, - "observations": [ - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "blob" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "blob" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "unicode": [ - { - "name": "unicode", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "result": "integer" - }, - { - "args": [ - "blob" - ], - "result": "integer" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "unistr": [ - { - "name": "unistr", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "unistr_quote": [ - { - "name": "unistr_quote", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "text" - } - ] - } - ], - "unixepoch": [ - { - "name": "unixepoch", - "type": "s", - "narg": -1, - "variadic": true, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "integer" - }, - { - "args": [ - "text" - ], - "result": "null" - }, - { - "args": [ - "blob" - ], - "result": "null" - }, - { - "args": [ - "null" - ], - "result": "null" - }, - { - "args": [ - "integer", - "integer" - ], - "result": "null" - }, - { - "args": [ - "integer", - "real" - ], - "result": "null" - }, - { - "args": [ - "integer", - "text" - ], - "result": "null" - }, - { - "args": [ - "integer", - "blob" - ], - "result": "null" - }, - { - "args": [ - "integer", - "null" - ], - "result": "null" - }, - { - "args": [ - "real", - "integer" - ], - "result": "null" - }, - { - "args": [ - "real", - "real" - ], - "result": "null" - }, - { - "args": [ - "real", - "text" - ], - "result": "null" - }, - { - "args": [ - "real", - "blob" - ], - "result": "null" - }, - { - "args": [ - "real", - "null" - ], - "result": "null" - }, - { - "args": [ - "text", - "integer" - ], - "result": "null" - }, - { - "args": [ - "text", - "real" - ], - "result": "null" - }, - { - "args": [ - "text", - "text" - ], - "result": "null" - }, - { - "args": [ - "text", - "blob" - ], - "result": "null" - }, - { - "args": [ - "text", - "null" - ], - "result": "null" - }, - { - "args": [ - "blob", - "integer" - ], - "result": "null" - }, - { - "args": [ - "blob", - "real" - ], - "result": "null" - }, - { - "args": [ - "blob", - "text" - ], - "result": "null" - }, - { - "args": [ - "blob", - "blob" - ], - "result": "null" - }, - { - "args": [ - "blob", - "null" - ], - "result": "null" - }, - { - "args": [ - "null", - "integer" - ], - "result": "null" - }, - { - "args": [ - "null", - "real" - ], - "result": "null" - }, - { - "args": [ - "null", - "text" - ], - "result": "null" - }, - { - "args": [ - "null", - "blob" - ], - "result": "null" - }, - { - "args": [ - "null", - "null" - ], - "result": "null" - } - ] - } - ], - "unlikely": [ - { - "name": "unlikely", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "integer" - }, - { - "args": [ - "real" - ], - "result": "real" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "upper": [ - { - "name": "upper", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "text" - }, - { - "args": [ - "real" - ], - "result": "text" - }, - { - "args": [ - "text" - ], - "result": "text" - }, - { - "args": [ - "blob" - ], - "result": "text" - }, - { - "args": [ - "null" - ], - "result": "null" - } - ] - } - ], - "zeroblob": [ - { - "name": "zeroblob", - "type": "s", - "narg": 1, - "variadic": false, - "observations": [ - { - "args": [ - "integer" - ], - "result": "blob" - }, - { - "args": [ - "real" - ], - "result": "blob" - }, - { - "args": [ - "text" - ], - "result": "blob" - }, - { - "args": [ - "blob" - ], - "result": "blob" - }, - { - "args": [ - "null" - ], - "result": "blob" - } - ] - } - ] - } -} diff --git a/src/types/sqlite/generate.ts b/src/types/sqlite/generate.ts deleted file mode 100644 index 42fc7016..00000000 --- a/src/types/sqlite/generate.ts +++ /dev/null @@ -1,475 +0,0 @@ -// SQLite function-signature inference tool. -// -// Phase 1.1 (SQLite generalization plan). -// -// Reads `pragma_function_list` from an in-memory sqlite instance, runs -// a typed input matrix through each function, and records the observed -// return types per input combination. Output is a JSON snapshot at -// `functions.json` that Phase 1.1 substep C will turn into TS class -// definitions. -// -// ----------------------------------------------------------------------- -// Known limits of runtime-only inference (fix later — see plan below): -// -// 1. Null-return ambiguity: `abs(NULL) → NULL` is legitimate null -// propagation; `datetime(-1) → NULL` is an *error signal*. Both look -// identical to `SELECT typeof(...)`. We can't tell whether a signature -// is "valid but nullable" or "invalid — reject at type level". -// 2. Nonsensical coercions surface as valid: SQLite quietly coerces -// X'01' (blob) → a numeric for `acos()`, so we emit `Blob.acos()`. -// Semantically wrong; a user would never write that. -// 3. Aggregates/windows probed with a specific arg type get bucketed -// onto that type: `Integer.count()` gets emitted because we probed -// count with an integer. `count` really belongs on the shared -// SqliteValue base (works over any expression). -// 4. Multi-arity overloads collapse: we keep only the shortest arity -// per (owner, name) to avoid TS "duplicate implementation" errors. -// `format()`, `substr(x,y)`/`substr(x,y,z)`, etc. lose overloads. -// 5. Heterogeneous arg combinations skipped entirely (see argTuples). -// `substr(text, int, int)` isn't emitted. -// -// ----------------------------------------------------------------------- -// Best final plan (defer to Phase 1.4-ish): -// -// LLM-over-docs with runtime as sanity check. Concretely: -// -// a. Fetch the SQLite doc pages (lang_corefunc.html, lang_datefunc.html, -// lang_aggfunc.html, lang_mathfunc.html, json1.html, windowfunctions.html) -// into a vendored snapshot. Version-pin to the sqlite build we -// target so codegen stays reproducible in CI. -// -// b. Provide the model a **deterministic template** — one JSON schema -// per function that must be filled: -// { -// name: string, -// overloads: [{ -// args: Array<{ type: SqliteType | "any", nullable: boolean, notes?: string }>, -// variadic: boolean, -// returnType: SqliteType | "arg[0]" | "arg[N]", // may reference args -// returnNullable: "propagates" | "always" | "on_error", -// kind: "scalar" | "aggregate" | "window", -// jsDoc: string -// }], -// } -// The schema forces the model to commit to null semantics -// (propagates vs error-signal) and canonical return types, which is -// exactly what runtime probing can't disambiguate. -// -// c. Batch by doc page (~20-30 functions each) to amortize prompt cost -// and keep the model's context focused on a coherent group. -// -// d. **Sanity check** by replaying this runtime tool's observations -// against the LLM output. Divergences are flagged, not silently -// preferred either way — a human confirms. Cases: -// - Model says arg X is invalid, runtime succeeds → probably fine -// (SQLite's affinity coercion is looser than docs). -// - Model says arg X returns Y, runtime returns Z → hard mismatch, -// block codegen until resolved. -// - Model omits a function pragma_function_list emits → block. -// -// e. Emit .ts from the *merged* signature (docs-primary, runtime-verified). -// Runtime file (this one) keeps generating `functions.json` as the -// inventory; the LLM step produces `signatures.json` on top. -// -// The current runtime-only output serves as a useful diff target for step -// (d) — divergences point at exactly the semantically-nonsense methods -// (Blob.acos etc.) that docs would prune. -// -// ----------------------------------------------------------------------- -// Current design choices (this file): -// - Same-type matrix (all args the same storage class) covers polymorphic -// dispatch on primary type: abs(int)→int, abs(real)→real, etc. -// Heterogeneous combinations (e.g. substr(text, int, int)) are skipped. -// - narg semantics: 0..N = fixed arity; -1 = variadic; -3 = "≥ 2" (min/max). -// Variadic gets probed at arity 1 and 2. narg > 3 skipped (rare). -// - Aggregates ('a') and window functions ('w') are noted but their -// return-type inference happens over a single-row grouping so `typeof()` -// works. Windows use OVER () so they compile as expressions. -// - Blob input literal is `X'01'` (a single byte, enough to trigger blob -// handling paths). -import Database from "better-sqlite3"; -import * as fs from "node:fs"; -import * as path from "node:path"; - -type SqliteType = "integer" | "real" | "text" | "blob" | "null"; -const TYPES: SqliteType[] = ["integer", "real", "text", "blob", "null"]; - -// SQL literal that produces each type. `typeof(literal)` returns the -// storage class name; we use these both as inputs and to key our matrix. -const LITERALS: Record = { - integer: "1", - real: "1.5", - text: "'x'", - blob: "X'01'", - null: "NULL", -}; - -interface FunctionRow { - name: string; - builtin: number; - type: "s" | "a" | "w"; - enc: string; - narg: number; - flags: number; -} - -interface Observation { - args: readonly SqliteType[]; - result?: SqliteType; - error?: string; -} - -interface FunctionSig { - name: string; - type: "s" | "a" | "w"; - narg: number; // raw from pragma; -1 variadic, -3 ≥2 - variadic: boolean; - observations: Observation[]; -} - -const listFunctions = (db: Database.Database): FunctionRow[] => { - return db - .prepare<[], FunctionRow>("SELECT name, builtin, type, enc, narg, flags FROM pragma_function_list ORDER BY name, narg") - .all(); -}; - -// Probe arities to try for a given narg. Positive → that exact arity. -// -1 (variadic) → 1, 2. -3 (min/max: ≥2) → 2, 3. Skip narg > 3. -const aritiesToProbe = (narg: number): number[] => { - if (narg === 0) {return [0];} - if (narg > 0 && narg <= 3) {return [narg];} - if (narg > 3) {return [];} // skip; hand-curate - if (narg === -1) {return [1, 2];} - if (narg === -3) {return [2, 3];} - return []; // unknown negative; skip -}; - -// Enumerate arg-type tuples for a given arity. For arity ≤ 2 we do the -// full 5^arity Cartesian product; for arity 3 we only do same-type tuples -// to keep the matrix small. -const argTuples = (arity: number): SqliteType[][] => { - if (arity === 0) {return [[]];} - if (arity === 1) {return TYPES.map((t) => [t]);} - if (arity === 2) {return TYPES.flatMap((a) => TYPES.map((b) => [a, b]));} - if (arity === 3) {return TYPES.map((t) => [t, t, t]);} - return []; -}; - -// Build the actual probe SQL. For scalar functions: `SELECT typeof(fn(...))`. -// For aggregates: same but wrap in a subquery so the aggregate has a row -// to consume. For windows: `SELECT typeof(fn(...) OVER ())` — again inside -// a subquery so there's data. -const probeSql = (fn: FunctionRow, args: SqliteType[]): string => { - const argList = args.map((t) => LITERALS[t]).join(", "); - const call = `${fn.name}(${argList})`; - if (fn.type === "s") { - return `SELECT typeof(${call}) AS t`; - } - if (fn.type === "a") { - // Aggregate needs rows to aggregate over. Feed a 1-row dummy. - return `SELECT typeof(${call}) AS t FROM (SELECT 1)`; - } - // Window - return `SELECT typeof(${call} OVER ()) AS t FROM (SELECT 1)`; -}; - -const probe = (db: Database.Database, fn: FunctionRow, args: SqliteType[]): Observation => { - const sql = probeSql(fn, args); - try { - const row = db.prepare(sql).get() as { t: string } | undefined; - const result = (row?.t ?? "null") as SqliteType; - return { args: [...args], result }; - } catch (e) { - return { args: [...args], error: (e as Error).message }; - } -}; - -const inferFunctionSig = (db: Database.Database, fn: FunctionRow): FunctionSig => { - const arities = aritiesToProbe(fn.narg); - const observations: Observation[] = []; - for (const a of arities) { - for (const tuple of argTuples(a)) { - observations.push(probe(db, fn, tuple)); - } - } - return { - name: fn.name, - type: fn.type, - narg: fn.narg, - variadic: fn.narg < 0, - observations, - }; -}; - -// Group by function name so overloads (same name, different arities like -// count(0), count(1)) show up as separate arity entries under one function. -const groupByName = (sigs: FunctionSig[]): { [name: string]: FunctionSig[] } => { - const acc = new Map(); - for (const s of sigs) { - const arr = acc.get(s.name) ?? []; - arr.push(s); - acc.set(s.name, arr); - } - return Object.fromEntries(acc); -}; - -// --- Class distribution + TS emission ----------------------------------- - -// Storage-class name → typegres class name. -const CLASS_FOR: Record, string> = { - integer: "Integer", - real: "Real", - text: "Text", - blob: "Blob", -}; - -// A method to emit on a class: name (camelCased), the SQL function name, -// the arg-type sequence (first arg is the receiver, so args[0] === owner), -// and the observed return storage class. -interface Method { - tsName: string; // e.g. "abs" - sqlName: string; // e.g. "abs" - ownerType: Exclude; - argTypes: readonly Exclude[]; // after arg[0] (owner) — remaining args - resultType: Exclude; - fnType: "s" | "a" | "w"; - variadic: boolean; -} - -// Camelcase without a dependency — small enough to inline. -const camel = (s: string): string => - s.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase()); - -// Distribute a function's observations into per-owner-type Methods. Rules: -// - Consider only "clean" same-type observations (all args same storage -// class, non-null result, no error). Heterogeneous overloads (e.g. -// substr(text, int, int)) are punted to hand-curated overrides. -// - For each type X where args=[X,...,X] gives result R (non-null), -// emit a method on X returning R. -// - Zero-arg functions (arity 0) become static on SqliteValue — collected -// separately below. -const methodsFor = (sig: FunctionSig): Method[] => { - const out: Method[] = []; - for (const obs of sig.observations) { - if (obs.error || !obs.result || obs.result === "null") {continue;} - if (obs.args.length === 0) {continue;} - const first = obs.args[0]!; - if (first === "null") {continue;} - const allSame = obs.args.every((a) => a === first); - if (!allSame) {continue;} // heterogeneous — defer - out.push({ - tsName: camel(sig.name), - sqlName: sig.name, - ownerType: first, - argTypes: obs.args.slice(1) as Exclude[], - resultType: obs.result as Exclude, - fnType: sig.type, - variadic: sig.variadic, - }); - } - return out; -}; - -// Deduplicate methods with the same (owner, tsName) — keep the shortest -// arity (usually the base overload; TS overloads require a unified -// implementation signature which the first-pass codegen doesn't emit, -// so multiple declarations per method name collide as duplicate -// implementations. Multi-arity overloads land in a follow-up). -const dedup = (methods: Method[]): Method[] => { - const seen = new Map(); - for (const m of methods) { - const k = `${m.ownerType}::${m.tsName}`; - const prev = seen.get(k); - if (!prev || m.argTypes.length < prev.argTypes.length) {seen.set(k, m);} - } - return [...seen.values()]; -}; - -// Whether an override for the given SQLite storage class exists under -// overrides/. Callers pass the override root (typically `src/types/sqlite`) -// so codegen:check with `--out-dir` still checks the committed overrides. -const overrideExistsFor = (overridesRoot: string, ownerType: string): boolean => - fs.existsSync(path.join(overridesRoot, "overrides", `${ownerType}.ts`)); - -const emitClassFile = ( - ownerType: Exclude, - methods: readonly Method[], - overridesRoot: string, -): string => { - const className = CLASS_FOR[ownerType]; - const argClass = (t: Exclude): string => `types.${CLASS_FOR[t]}`; - const lines: string[] = []; - lines.push("// Auto-generated by src/types/sqlite/generate.ts — do not edit."); - lines.push("// One method per (owner-type, function-name); same-type-args only."); - lines.push("// Heterogeneous overloads (e.g. substr) will be added via hand-"); - lines.push("// curated overrides (Phase 1.4)."); - lines.push('import { SqliteValue } from "../base";'); - lines.push('import { sql, type Sql } from "../../../builder/sql";'); - lines.push('import { meta } from "../../sql-value";'); - lines.push('import * as runtime from "../../runtime";'); - lines.push('import * as types from "../index";'); - lines.push(""); - lines.push(`export class ${className} extends SqliteValue {`); - lines.push(" declare [meta]: {"); - lines.push(` __class: typeof ${className};`); - lines.push(" __raw: Sql;"); - lines.push(" __nullability: N;"); - lines.push(` __nullable: ${className}<0 | 1>;`); - lines.push(` __nonNullable: ${className}<1>;`); - lines.push(` __aggregate: ${className};`); - lines.push(` __any: ${className};`); - lines.push(" };"); - lines.push(` static override __typname = sql\`${ownerType.toUpperCase()}\`;`); - lines.push(` static override __typnameText = "${ownerType}";`); - // Return-type marker for TsTypeOf. Overrides under overrides/ provide - // the runtime parser AND a narrower return type (integer/real → - // number, bool → boolean). Codegen still emits a `declare` here for - // the classes that don't have an override (text → string, blob → - // Uint8Array) so their rows type correctly. - const declaredTsType: Record, string> = { - integer: "number", - real: "number", - text: "string", - blob: "Uint8Array", - }; - if (!overrideExistsFor(overridesRoot, ownerType)) { - lines.push(` declare deserialize: (raw: string) => ${declaredTsType[ownerType]};`); - } - lines.push(""); - - // Per-storage-class JS primitive that gets accepted alongside the - // typegres instance. Blob has no meaningful JS primitive so its - // methods reject non-Blob args at runtime (see registry sentinel). - const primitiveOf: Record, string | null> = { - integer: "number", - real: "number", - text: "string", - blob: null, - }; - for (const m of methods) { - const retClass = argClass(m.resultType); - const params = m.argTypes.map((t, i) => { - const prim = primitiveOf[t]; - const tParam = prim - ? `M${i} extends ${argClass(t)} | ${prim}` - : `M${i} extends ${argClass(t)}`; - return { tParam, argParam: `arg${i}: M${i}` }; - }); - const tsGenerics = params.length > 0 - ? `<${params.map((p) => p.tParam).join(", ")}>` - : ""; - const paramList = params.map((p) => p.argParam).join(", "); - const nullTerms = ["N", ...m.argTypes.map((_, i) => `runtime.NullOf`)]; - const nullExpr = nullTerms.length === 1 ? nullTerms[0]! : `runtime.StrictNull<${nullTerms.join(" | ")}>`; - // Runtime dispatch via runtime.match for arg validation + serialization, - // then runtime.funcCall for the actual Func node (dialect-tagged via - // the target return type's static .dialect). - const matchers = m.argTypes.map((t) => { - const prim = primitiveOf[t]; - return prim - ? `{ type: ${argClass(t)}, allowPrimitive: true }` - : `{ type: ${argClass(t)} }`; - }).join(", "); - const inputArgs = m.argTypes.map((_, i) => `arg${i}`).join(", "); - lines.push(` ${m.tsName}${tsGenerics}(${paramList}): ${retClass}<${nullExpr}> {`); - lines.push(` const [__rt, ...__rest] = runtime.match([${inputArgs}], [[[${matchers}], ${retClass}]]);`); - lines.push(` return runtime.funcCall("${m.sqlName}", [this, ...__rest], __rt) as ${retClass}<${nullExpr}>;`); - lines.push(" }"); - } - lines.push("}"); - lines.push(""); - return lines.join("\n"); -}; - -const emitClasses = ( - sigs: FunctionSig[], - generatedDir: string, - overridesRoot: string, -): void => { - const allMethods = sigs.flatMap(methodsFor); - const byOwner: Record, Method[]> = { - integer: [], real: [], text: [], blob: [], - }; - for (const m of allMethods) { - byOwner[m.ownerType].push(m); - } - - for (const owner of Object.keys(byOwner) as Exclude[]) { - const methods = dedup(byOwner[owner]).sort((a, b) => a.tsName.localeCompare(b.tsName)); - const src = emitClassFile(owner, methods, overridesRoot); - const out = path.join(generatedDir, `${owner}.ts`); - fs.writeFileSync(out, src); - console.log(` ${owner}.ts: ${methods.length} methods`); - } -}; - -const main = () => { - const db = new Database(":memory:"); - const sqliteVersion = (db.prepare("SELECT sqlite_version() AS v").get() as { v: string }).v; - const functions = listFunctions(db); - - const sigs: FunctionSig[] = []; - for (const fn of functions) { - sigs.push(inferFunctionSig(db, fn)); - } - db.close(); - - const output = { - sqlite_version: sqliteVersion, - generated_at: new Date().toISOString(), - function_count: functions.length, - functions: groupByName(sigs), - }; - - const outDirFlag = process.argv.indexOf("--out-dir"); - const outDir = outDirFlag >= 0 - ? path.resolve(process.argv[outDirFlag + 1]!) - : path.resolve(import.meta.dirname); - // Create both outDir and outDir/generated up front so the JSON write - // below doesn't ENOENT when `--out-dir` points at a fresh tmp path - // (codegen:check). - const generatedDir = path.join(outDir, "generated"); - fs.mkdirSync(generatedDir, { recursive: true }); - const jsonPath = path.join(outDir, "functions.json"); - fs.writeFileSync(jsonPath, JSON.stringify(output, null, 2) + "\n"); - console.log(`Wrote ${functions.length} functions to ${jsonPath}`); - // codegen:check writes to a tmp dir but the committed overrides - // still live under `src/types/sqlite/overrides/`. Point the - // override-detection helper at the source tree so `--out-dir` - // runs see the same override set as a normal codegen run. - const overridesRoot = path.resolve(import.meta.dirname); - emitClasses(sigs, generatedDir, overridesRoot); - // Barrel always targets the committed source path (matches PG codegen). - // The re-emit is idempotent — a `--out-dir` (codegen:check) run rewrites - // the same block back to the same file with the same content, and the - // diff step only inspects the `generated/` subdir anyway. - updateBarrel(path.join(overridesRoot, "index.ts")); -}; - -// Rewrite the [generated-start]...[generated-end] block of index.ts to -// list all classes we just emitted. Classes that have a hand-written -// override under overrides/.ts are re-exported from there; -// everything else comes straight from generated/. -const updateBarrel = (barrelPath: string): void => { - const classes = ["Blob", "Bool", "Integer", "Real", "Text"]; - const overridesDir = path.join(path.dirname(barrelPath), "overrides"); - const hasOverride = (c: string): boolean => - fs.existsSync(path.join(overridesDir, `${c.toLowerCase()}.ts`)); - const block = - "// [generated-start]\n" + - classes - .map((c) => { - const dir = hasOverride(c) ? "overrides" : "generated"; - return `export { ${c} } from "./${dir}/${c.toLowerCase()}";`; - }) - .join("\n") + - "\n// [generated-end]"; - const cur = fs.readFileSync(barrelPath, "utf8"); - const next = cur.replace( - /\/\/ \[generated-start\][\s\S]*?\/\/ \[generated-end\]/, - block, - ); - fs.writeFileSync(barrelPath, next); -}; - -main(); diff --git a/src/types/sqlite/generated/any.ts b/src/types/sqlite/generated/any.ts new file mode 100644 index 00000000..67684b4e --- /dev/null +++ b/src/types/sqlite/generated/any.ts @@ -0,0 +1,173 @@ +// Auto-generated by src/types/sqlite/emit.ts from docs/*.json — do not edit. +// The generated half of the SQLite root class (hand-written core — +// dialect metadata, isNull/isNotNull/in — extends this in +// ../overrides/any.ts). Carries ONLY the universal methods (receiver +// domain "any"). +// Methods are placed by their receiver (first) argument's documented +// domain — runtime dispatch IS the type system for RPC callers +// (exoeval), so a value only carries the methods honest for its +// storage class. +// Every method: typed overload declarations over a runtime.match +// implementation (arg validation + primitive serialization + return +// class per matched overload — same dispatch model as PG). +import * as runtime from "../../runtime"; +import { meta } from "../../sql-value"; +import { expose } from "../../../exoeval/tool"; +import { SqlValue } from "../../sql-value"; +import * as types from "../index"; + +export class Any extends SqlValue { + /** `concat` — Concatenation of all non-NULL args (3.44+). */ + @expose.unchecked() + concat(...rest: (types.Any | number | string | boolean | Uint8Array)[]): types.Text<1> { const [__rt, ...__rest] = runtime.match([...rest], [[[{ type: types.Any, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("concat", [this, ...__rest], __rt) as any; } + /** `hex` — Uppercase hex rendering of the blob-coerced value; hex(NULL) = ''. */ + @expose.unchecked() + hex(): types.Text<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("hex", [this, ...__rest], __rt) as any; } + /** `max` — Scalar max of 2+ values (SQLite cross-type ordering). */ + max | number | string | boolean | Uint8Array>(arg0: M0, ...rest: (types.Any | number | string | boolean | Uint8Array)[]): types.Any>>; + /** `max` — Maximum value; NULL over the empty set. */ + max>(this: T): T extends { [meta]: { __nullable: infer U } } ? U : types.Any<0 | 1>; + @expose.unchecked() + max(this: any, ...args: unknown[]): any { const [__rt, ...__rest] = runtime.match(args, [[[{ type: types.Any, allowPrimitive: true }, { type: types.Any, allowPrimitive: true, rest: true }], types.Any], [[], runtime.pgType(this)]]); return runtime.funcCall("max", [this, ...__rest], __rt) as any; } + /** `min` — Scalar min of 2+ values (SQLite cross-type ordering). */ + min | number | string | boolean | Uint8Array>(arg0: M0, ...rest: (types.Any | number | string | boolean | Uint8Array)[]): types.Any>>; + /** `min` — Minimum value; NULL over the empty set. */ + min>(this: T): T extends { [meta]: { __nullable: infer U } } ? U : types.Any<0 | 1>; + @expose.unchecked() + min(this: any, ...args: unknown[]): any { const [__rt, ...__rest] = runtime.match(args, [[[{ type: types.Any, allowPrimitive: true }, { type: types.Any, allowPrimitive: true, rest: true }], types.Any], [[], runtime.pgType(this)]]); return runtime.funcCall("min", [this, ...__rest], __rt) as any; } + /** `quote` — SQL-literal rendering; quote(NULL) = 'NULL'. */ + @expose.unchecked() + quote(): types.Text<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("quote", [this, ...__rest], __rt) as any; } + /** `typeof` — Storage class name: 'integer'|'real'|'text'|'blob'|'null'. */ + @expose.unchecked() + typeof(): types.Text<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("typeof", [this, ...__rest], __rt) as any; } + /** `unistr_quote` — quote() but escaping non-ASCII via \u (3.50+). */ + @expose.unchecked() + unistrQuote(): types.Text<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("unistr_quote", [this, ...__rest], __rt) as any; } + /** `ifnull` — coalesce() with exactly two args. */ + @expose.unchecked() + ifnull | number | string | boolean | Uint8Array>(arg0: M0): types.Any<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Any]]); return runtime.funcCall("ifnull", [this, ...__rest], __rt) as any; } + /** `nullif` — NULL when X = Y, else X. */ + @expose.unchecked() + nullif>(this: T, arg0: types.Any | number | string | boolean | Uint8Array): T extends { [meta]: { __nullable: infer U } } ? U : types.Any<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], runtime.pgType(this)]]); return runtime.funcCall("nullif", [this, ...__rest], __rt) as any; } + /** `date` — YYYY-MM-DD for the given time value + modifiers. */ + date | string>(arg0?: M0, ...rest: (types.Text | string)[]): types.Text<0 | 1>; + @expose.unchecked() + date(...args: unknown[]): any { const [__rt, ...__rest] = runtime.match(args, [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("date", [this, ...__rest], __rt) as any; } + /** `time` — HH:MM:SS for the given time value + modifiers. */ + time | string>(arg0?: M0, ...rest: (types.Text | string)[]): types.Text<0 | 1>; + @expose.unchecked() + time(...args: unknown[]): any { const [__rt, ...__rest] = runtime.match(args, [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("time", [this, ...__rest], __rt) as any; } + /** `datetime` — YYYY-MM-DD HH:MM:SS for the given time value + modifiers. */ + datetime | string>(arg0?: M0, ...rest: (types.Text | string)[]): types.Text<0 | 1>; + @expose.unchecked() + datetime(...args: unknown[]): any { const [__rt, ...__rest] = runtime.match(args, [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("datetime", [this, ...__rest], __rt) as any; } + /** `julianday` — Julian day number (REAL). */ + julianday | string>(arg0?: M0, ...rest: (types.Text | string)[]): types.Real<0 | 1>; + @expose.unchecked() + julianday(...args: unknown[]): any { const [__rt, ...__rest] = runtime.match(args, [[[], types.Real], [[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Real]]); return runtime.funcCall("julianday", [this, ...__rest], __rt) as any; } + /** `unixepoch` — Unix timestamp (INTEGER; add 'subsec' for REAL). */ + unixepoch | string>(arg0?: M0, ...rest: (types.Text | string)[]): types.Integer<0 | 1>; + @expose.unchecked() + unixepoch(...args: unknown[]): any { const [__rt, ...__rest] = runtime.match(args, [[[], types.Integer], [[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Integer]]); return runtime.funcCall("unixepoch", [this, ...__rest], __rt) as any; } + /** `timediff` — Human-readable A − B duration (3.43+). */ + @expose.unchecked() + timediff | number | string | boolean | Uint8Array>(arg0: M0): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("timediff", [this, ...__rest], __rt) as any; } + /** `avg` — Mean of non-NULL values; NULL over the empty set. */ + @expose.unchecked() + avg(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("avg", [this, ...__rest], __rt) as any; } + /** `count` — Count of non-NULL values. */ + @expose.unchecked() + count(): types.Integer<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("count", [this, ...__rest], __rt) as any; } + /** `group_concat` — Concatenation of non-NULL values with separator (default ','). */ + groupConcat | string>(arg0?: M0): types.Text<0 | 1>; + @expose.unchecked() + groupConcat(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.funcCall("group_concat", [this, ...__rest], __rt) as any; } + /** `string_agg` — Alias of group_concat(X, SEP) (3.44+). */ + @expose.unchecked() + stringAgg | string>(arg0: M0): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.funcCall("string_agg", [this, ...__rest], __rt) as any; } + /** `total` — Sum as REAL; 0.0 over the empty set, never NULL. */ + @expose.unchecked() + total(): types.Real<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("total", [this, ...__rest], __rt) as any; } + /** `json_array` — JSON array from the arguments. */ + @expose.unchecked() + jsonArray(...rest: (types.Any | number | string | boolean | Uint8Array)[]): types.Text<1> { const [__rt, ...__rest] = runtime.match([...rest], [[[{ type: types.Any, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("json_array", [this, ...__rest], __rt) as any; } + /** `jsonb_array` — JSON array from the arguments. */ + @expose.unchecked() + jsonbArray(...rest: (types.Any | number | string | boolean | Uint8Array)[]): types.Blob<1> { const [__rt, ...__rest] = runtime.match([...rest], [[[{ type: types.Any, allowPrimitive: true, rest: true }], types.Blob]]); return runtime.funcCall("jsonb_array", [this, ...__rest], __rt) as any; } + /** `json_quote` — SQL value → JSON representation. */ + @expose.unchecked() + jsonQuote(): types.Text<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("json_quote", [this, ...__rest], __rt) as any; } + /** `json_valid` — 1 if X is well-formed RFC-8259 JSON text. */ + @expose.unchecked() + jsonValid(): types.Bool { const [__rt, ...__rest] = runtime.match([], [[[], types.Bool]]); return runtime.funcCall("json_valid", [this, ...__rest], __rt) as any; } + /** `json_group_array` — Aggregate values into a JSON array ('[]' for empty). */ + @expose.unchecked() + jsonGroupArray(): types.Text<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("json_group_array", [this, ...__rest], __rt) as any; } + /** `jsonb_group_array` — Aggregate values into a JSONB array. */ + @expose.unchecked() + jsonbGroupArray(): types.Blob<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); return runtime.funcCall("jsonb_group_array", [this, ...__rest], __rt) as any; } + /** `=` — Equality (SQL three-valued). */ + @expose.unchecked() + ['='] | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`=`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `=` — Equality (SQL three-valued). */ + @expose.unchecked() + eq | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`=`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `<>` — Inequality (SQL three-valued). */ + @expose.unchecked() + ['<>'] | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`<>`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `<>` — Inequality (SQL three-valued). */ + @expose.unchecked() + ne | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`<>`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `<` — Less-than under SQLite's cross-type ordering. */ + @expose.unchecked() + ['<'] | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`<`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `<` — Less-than under SQLite's cross-type ordering. */ + @expose.unchecked() + lt | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`<`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `<=` — Less-or-equal. */ + @expose.unchecked() + ['<='] | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`<=`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `<=` — Less-or-equal. */ + @expose.unchecked() + lte | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`<=`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `>` — Greater-than. */ + @expose.unchecked() + ['>'] | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`>`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `>` — Greater-than. */ + @expose.unchecked() + gt | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`>`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `>=` — Greater-or-equal. */ + @expose.unchecked() + ['>='] | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`>=`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `>=` — Greater-or-equal. */ + @expose.unchecked() + gte | number | string | boolean | Uint8Array>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`>=`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `IS` — NULL-safe equality — never NULL. */ + @expose.unchecked() + ['IS'] | number | string | boolean | Uint8Array>(arg0: M0): types.Bool<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`IS`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `IS` — NULL-safe equality — never NULL. */ + @expose.unchecked() + is | number | string | boolean | Uint8Array>(arg0: M0): types.Bool<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`IS`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `IS NOT` — NULL-safe inequality — never NULL. */ + @expose.unchecked() + ['IS NOT'] | number | string | boolean | Uint8Array>(arg0: M0): types.Bool<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`IS NOT`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `IS NOT` — NULL-safe inequality — never NULL. */ + @expose.unchecked() + isNot | number | string | boolean | Uint8Array>(arg0: M0): types.Bool<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`IS NOT`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `IS DISTINCT FROM` — Synonym for IS NOT. */ + @expose.unchecked() + ['IS DISTINCT FROM'] | number | string | boolean | Uint8Array>(arg0: M0): types.Bool<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`IS DISTINCT FROM`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `IS DISTINCT FROM` — Synonym for IS NOT. */ + @expose.unchecked() + isDistinctFrom | number | string | boolean | Uint8Array>(arg0: M0): types.Bool<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`IS DISTINCT FROM`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `IS NOT DISTINCT FROM` — Synonym for IS. */ + @expose.unchecked() + ['IS NOT DISTINCT FROM'] | number | string | boolean | Uint8Array>(arg0: M0): types.Bool<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`IS NOT DISTINCT FROM`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `IS NOT DISTINCT FROM` — Synonym for IS. */ + @expose.unchecked() + isNotDistinctFrom | number | string | boolean | Uint8Array>(arg0: M0): types.Bool<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Bool]]); return runtime.opCall(runtime.sql`IS NOT DISTINCT FROM`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `||` — String concatenation. */ + @expose.unchecked() + ['||'] | number | string | boolean | Uint8Array>(arg0: M0): types.Text>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.opCall(runtime.sql`||`, [this, ...__rest] as [unknown, unknown], __rt) as any; } +} diff --git a/src/types/sqlite/generated/blob.ts b/src/types/sqlite/generated/blob.ts index 385a0f6c..67c1f8da 100644 --- a/src/types/sqlite/generated/blob.ts +++ b/src/types/sqlite/generated/blob.ts @@ -1,329 +1,127 @@ -// Auto-generated by src/types/sqlite/generate.ts — do not edit. -// One method per (owner-type, function-name); same-type-args only. -// Heterogeneous overloads (e.g. substr) will be added via hand- -// curated overrides (Phase 1.4). -import { SqliteValue } from "../base"; -import { sql, type Sql } from "../../../builder/sql"; -import { meta } from "../../sql-value"; +// Auto-generated by src/types/sqlite/emit.ts from docs/*.json — do not edit. +// Blob — the blob storage-class view: the __view brand +// (near-identical subclasses are otherwise structurally +// interchangeable, defeating nominal checks), [meta]/typname chrome, +// and the methods whose receiver domain is blob. Hand-written +// behavior (deserialize, acceptsPrimitive) extends this in +// ../overrides/blob.ts. +// Methods are placed by their receiver (first) argument's documented +// domain — runtime dispatch IS the type system for RPC callers +// (exoeval), so a value only carries the methods honest for its +// storage class. +// Every method: typed overload declarations over a runtime.match +// implementation (arg validation + primitive serialization + return +// class per matched overload — same dispatch model as PG). import * as runtime from "../../runtime"; +import { meta } from "../../sql-value"; +import { expose } from "../../../exoeval/tool"; +import { Any } from "../overrides/any"; import * as types from "../index"; -export class Blob extends SqliteValue { +export class Blob extends Any { + declare readonly __view: "blob"; declare [meta]: { - __class: typeof Blob; - __raw: Sql; + __class: typeof types.Blob; + __raw: runtime.Sql; __nullability: N; - __nullable: Blob<0 | 1>; - __nonNullable: Blob<1>; - __aggregate: Blob; - __any: Blob; + __nullable: types.Blob<0 | 1>; + __nonNullable: types.Blob<1>; + __aggregate: types.Blob; + __any: types.Blob; }; - static override __typname = sql`BLOB`; + static override __typname = runtime.sql`BLOB`; static override __typnameText = "blob"; - declare deserialize: (raw: string) => Uint8Array; - abs(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("abs", [this, ...__rest], __rt) as types.Real; - } - avg(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("avg", [this, ...__rest], __rt) as types.Real; - } - char(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("char", [this, ...__rest], __rt) as types.Text; - } - concat>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Text]]); - return runtime.funcCall("concat", [this, ...__rest], __rt) as types.Text>>; - } - count(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("count", [this, ...__rest], __rt) as types.Integer; - } - firstValue(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("first_value", [this, ...__rest], __rt) as types.Blob; - } - format(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("format", [this, ...__rest], __rt) as types.Text; - } - fts5Insttoken(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("fts5_insttoken", [this, ...__rest], __rt) as types.Blob; - } - fts5Locale>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Blob]]); - return runtime.funcCall("fts5_locale", [this, ...__rest], __rt) as types.Blob>>; - } - glob>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Integer]]); - return runtime.funcCall("glob", [this, ...__rest], __rt) as types.Integer>>; - } - groupConcat(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("group_concat", [this, ...__rest], __rt) as types.Text; - } - hex(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("hex", [this, ...__rest], __rt) as types.Text; - } - ifnull>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Blob]]); - return runtime.funcCall("ifnull", [this, ...__rest], __rt) as types.Blob>>; - } - instr>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Integer]]); - return runtime.funcCall("instr", [this, ...__rest], __rt) as types.Integer>>; - } - json(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json", [this, ...__rest], __rt) as types.Text; - } - jsonArray(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_array", [this, ...__rest], __rt) as types.Text; - } - jsonArrayInsert(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_array_insert", [this, ...__rest], __rt) as types.Text; - } - jsonArrayLength(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_array_length", [this, ...__rest], __rt) as types.Integer; - } - jsonb(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb", [this, ...__rest], __rt) as types.Blob; - } - jsonbArray(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_array", [this, ...__rest], __rt) as types.Blob; - } - jsonbArrayInsert(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_array_insert", [this, ...__rest], __rt) as types.Blob; - } - jsonbGroupArray(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_group_array", [this, ...__rest], __rt) as types.Blob; - } - jsonbGroupObject>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Blob]]); - return runtime.funcCall("jsonb_group_object", [this, ...__rest], __rt) as types.Blob>>; - } - jsonbInsert(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_insert", [this, ...__rest], __rt) as types.Blob; - } - jsonbPatch>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Blob]]); - return runtime.funcCall("jsonb_patch", [this, ...__rest], __rt) as types.Blob>>; - } - jsonbRemove(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_remove", [this, ...__rest], __rt) as types.Blob; - } - jsonbReplace(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_replace", [this, ...__rest], __rt) as types.Blob; - } - jsonbSet(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_set", [this, ...__rest], __rt) as types.Blob; - } - jsonErrorPosition(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_error_position", [this, ...__rest], __rt) as types.Integer; - } - jsonGroupArray(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_group_array", [this, ...__rest], __rt) as types.Text; - } - jsonGroupObject>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Text]]); - return runtime.funcCall("json_group_object", [this, ...__rest], __rt) as types.Text>>; - } - jsonInsert(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_insert", [this, ...__rest], __rt) as types.Text; - } - jsonPatch>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Text]]); - return runtime.funcCall("json_patch", [this, ...__rest], __rt) as types.Text>>; - } - jsonPretty(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_pretty", [this, ...__rest], __rt) as types.Text; - } - jsonQuote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_quote", [this, ...__rest], __rt) as types.Text; - } - jsonRemove(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_remove", [this, ...__rest], __rt) as types.Text; - } - jsonReplace(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_replace", [this, ...__rest], __rt) as types.Text; - } - jsonSet(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_set", [this, ...__rest], __rt) as types.Text; - } - jsonType(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_type", [this, ...__rest], __rt) as types.Text; - } - jsonValid(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_valid", [this, ...__rest], __rt) as types.Integer; - } - lag>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Blob]]); - return runtime.funcCall("lag", [this, ...__rest], __rt) as types.Blob>>; - } - lastValue(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("last_value", [this, ...__rest], __rt) as types.Blob; - } - lead>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Blob]]); - return runtime.funcCall("lead", [this, ...__rest], __rt) as types.Blob>>; - } - length(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("length", [this, ...__rest], __rt) as types.Integer; - } - like>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Integer]]); - return runtime.funcCall("like", [this, ...__rest], __rt) as types.Integer>>; - } - likely(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("likely", [this, ...__rest], __rt) as types.Blob; - } - lower(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("lower", [this, ...__rest], __rt) as types.Text; - } - ltrim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("ltrim", [this, ...__rest], __rt) as types.Text; - } - max(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("max", [this, ...__rest], __rt) as types.Blob; - } - min(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("min", [this, ...__rest], __rt) as types.Blob; - } - octetLength(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("octet_length", [this, ...__rest], __rt) as types.Integer; - } - printf(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("printf", [this, ...__rest], __rt) as types.Text; - } - quote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("quote", [this, ...__rest], __rt) as types.Text; - } - randomblob(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("randomblob", [this, ...__rest], __rt) as types.Blob; - } - replace, M1 extends types.Blob>(arg0: M0, arg1: M1): types.Text | runtime.NullOf>> { - const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Blob }, { type: types.Blob }], types.Text]]); - return runtime.funcCall("replace", [this, ...__rest], __rt) as types.Text | runtime.NullOf>>; - } - round(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("round", [this, ...__rest], __rt) as types.Real; - } - rtrim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("rtrim", [this, ...__rest], __rt) as types.Text; - } - soundex(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("soundex", [this, ...__rest], __rt) as types.Text; - } - sqliteCompileoptionGet(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("sqlite_compileoption_get", [this, ...__rest], __rt) as types.Text; - } - sqliteCompileoptionUsed(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("sqlite_compileoption_used", [this, ...__rest], __rt) as types.Integer; - } - strftime(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("strftime", [this, ...__rest], __rt) as types.Text; - } - stringAgg>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Text]]); - return runtime.funcCall("string_agg", [this, ...__rest], __rt) as types.Text>>; - } - substr>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Blob]]); - return runtime.funcCall("substr", [this, ...__rest], __rt) as types.Blob>>; - } - substring>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Blob]]); - return runtime.funcCall("substring", [this, ...__rest], __rt) as types.Blob>>; - } - subtype(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("subtype", [this, ...__rest], __rt) as types.Integer; - } - sum(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("sum", [this, ...__rest], __rt) as types.Real; - } - total(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("total", [this, ...__rest], __rt) as types.Real; - } - trim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("trim", [this, ...__rest], __rt) as types.Text; - } - typeof(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("typeof", [this, ...__rest], __rt) as types.Text; - } - unhex>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob }], types.Blob]]); - return runtime.funcCall("unhex", [this, ...__rest], __rt) as types.Blob>>; - } - unicode(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("unicode", [this, ...__rest], __rt) as types.Integer; - } - unistr(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("unistr", [this, ...__rest], __rt) as types.Text; - } - unistrQuote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("unistr_quote", [this, ...__rest], __rt) as types.Text; - } - unlikely(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("unlikely", [this, ...__rest], __rt) as types.Blob; - } - upper(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("upper", [this, ...__rest], __rt) as types.Text; - } - zeroblob(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("zeroblob", [this, ...__rest], __rt) as types.Blob; - } + /** `instr` — 1-based position of the first occurrence of Y in X; 0 if absent. */ + @expose.unchecked() + instr | Uint8Array>(arg0: M0): types.Integer>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Blob, allowPrimitive: true }], types.Integer]]); return runtime.funcCall("instr", [this, ...__rest], __rt) as any; } + /** `length` — Characters for TEXT, bytes for BLOB. */ + @expose.unchecked() + length(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("length", [this, ...__rest], __rt) as any; } + /** `octet_length` — Length in bytes after TEXT encoding. */ + @expose.unchecked() + octetLength(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("octet_length", [this, ...__rest], __rt) as any; } + /** `substr` — Substring from 1-based Y, length Z (to end if omitted). Empty-blob input yields NULL. */ + substr | number, M1 extends types.Integer | number>(arg0: M0, arg1?: M1): types.Blob<0 | 1>; + @expose.unchecked() + substr(arg0: unknown, arg1?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Integer, allowPrimitive: true }], types.Blob], [[{ type: types.Integer, allowPrimitive: true }, { type: types.Integer, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("substr", [this, ...__rest], __rt) as any; } + /** `substring` — Alias of substr(). Empty-blob input yields NULL. */ + substring | number, M1 extends types.Integer | number>(arg0: M0, arg1?: M1): types.Blob<0 | 1>; + @expose.unchecked() + substring(arg0: unknown, arg1?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Integer, allowPrimitive: true }], types.Blob], [[{ type: types.Integer, allowPrimitive: true }, { type: types.Integer, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("substring", [this, ...__rest], __rt) as any; } + /** `json` — Validate + minify JSON (jsonb → binary). */ + @expose.unchecked() + json(): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("json", [this, ...__rest], __rt) as any; } + /** `jsonb` — Validate + minify JSON (jsonb → binary). */ + @expose.unchecked() + jsonb(): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); return runtime.funcCall("jsonb", [this, ...__rest], __rt) as any; } + /** `json_array_length` — Array length at path (default '$'). */ + jsonArrayLength | string>(arg0?: M0): types.Integer<0 | 1>; + @expose.unchecked() + jsonArrayLength(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Integer], [[{ type: types.Text, allowPrimitive: true }], types.Integer]]); return runtime.funcCall("json_array_length", [this, ...__rest], __rt) as any; } + /** `json_error_position` — 0 if well-formed, else 1-based position of the first error. */ + @expose.unchecked() + jsonErrorPosition(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("json_error_position", [this, ...__rest], __rt) as any; } + /** `json_extract` — Extract value(s) at path(s) — SQL value for scalars, JSON text otherwise. */ + @expose.unchecked() + jsonExtract | string>(arg0: M0, ...rest: (types.Text | string)[]): types.Any<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Any]]); return runtime.funcCall("json_extract", [this, ...__rest], __rt) as any; } + /** `jsonb_extract` — Extract at path(s) — JSONB for objects/arrays, SQL value for scalars. */ + @expose.unchecked() + jsonbExtract | string>(arg0: M0, ...rest: (types.Text | string)[]): types.Any<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Any]]); return runtime.funcCall("jsonb_extract", [this, ...__rest], __rt) as any; } + /** `json_insert` — Insert value at path if absent (more path/value pairs may follow). */ + @expose.unchecked() + jsonInsert | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_insert", [this, ...__rest], __rt) as any; } + /** `jsonb_insert` — Insert value at path if absent (more path/value pairs may follow). */ + @expose.unchecked() + jsonbInsert | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_insert", [this, ...__rest], __rt) as any; } + /** `json_array_insert` — Insert value into array at element path, shifting later elements (3.51+). */ + @expose.unchecked() + jsonArrayInsert | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_array_insert", [this, ...__rest], __rt) as any; } + /** `jsonb_array_insert` — Insert value into array at element path, shifting later elements (3.51+). */ + @expose.unchecked() + jsonbArrayInsert | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_array_insert", [this, ...__rest], __rt) as any; } + /** `json_patch` — RFC-7396 MergePatch of Y into X. */ + @expose.unchecked() + jsonPatch | number | string | boolean | Uint8Array>(arg0: M0): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_patch", [this, ...__rest], __rt) as any; } + /** `jsonb_patch` — RFC-7396 MergePatch of Y into X. */ + @expose.unchecked() + jsonbPatch | number | string | boolean | Uint8Array>(arg0: M0): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_patch", [this, ...__rest], __rt) as any; } + /** `json_pretty` — Pretty-print JSON (3.46+). */ + jsonPretty | string>(arg0?: M0): types.Text<0 | 1>; + @expose.unchecked() + jsonPretty(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_pretty", [this, ...__rest], __rt) as any; } + /** `json_remove` — Remove the value(s) at path(s). */ + @expose.unchecked() + jsonRemove | string>(arg0: M0, ...rest: (types.Text | string)[]): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("json_remove", [this, ...__rest], __rt) as any; } + /** `jsonb_remove` — Remove the value(s) at path(s). */ + @expose.unchecked() + jsonbRemove | string>(arg0: M0, ...rest: (types.Text | string)[]): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Blob]]); return runtime.funcCall("jsonb_remove", [this, ...__rest], __rt) as any; } + /** `json_replace` — Replace value at path if present (more path/value pairs may follow). */ + @expose.unchecked() + jsonReplace | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_replace", [this, ...__rest], __rt) as any; } + /** `jsonb_replace` — Replace value at path if present (more path/value pairs may follow). */ + @expose.unchecked() + jsonbReplace | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_replace", [this, ...__rest], __rt) as any; } + /** `json_set` — Set value at path — insert or replace (more path/value pairs may follow). */ + @expose.unchecked() + jsonSet | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_set", [this, ...__rest], __rt) as any; } + /** `jsonb_set` — Set value at path — insert or replace (more path/value pairs may follow). */ + @expose.unchecked() + jsonbSet | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_set", [this, ...__rest], __rt) as any; } + /** `json_type` — 'object'|'array'|'integer'|... at path; NULL if path absent. */ + jsonType | string>(arg0?: M0): types.Text<0 | 1>; + @expose.unchecked() + jsonType(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_type", [this, ...__rest], __rt) as any; } + /** `json_each` — Table-valued: one row per element of the top-level array/object (or of the value at PATH). */ + @expose.unchecked() + jsonEach | string>(arg0?: M0): runtime.Srf<{ key: types.Any<1>; value: types.Any<1>; type: types.Text<1>; atom: types.Any<1>; id: types.Integer<1>; parent: types.Integer<1>; fullkey: types.Text<1>; path: types.Text<1> }, "json_each"> { return new runtime.Srf("json_each", [this, arg0].filter((a) => a !== undefined), [["key", types.Any], ["value", types.Any], ["type", types.Text], ["atom", types.Any], ["id", types.Integer], ["parent", types.Integer], ["fullkey", types.Text], ["path", types.Text]]) as any; } + /** `json_tree` — Table-valued: recursive walk of the whole JSON tree, one row per container and leaf. */ + @expose.unchecked() + jsonTree | string>(arg0?: M0): runtime.Srf<{ key: types.Any<1>; value: types.Any<1>; type: types.Text<1>; atom: types.Any<1>; id: types.Integer<1>; parent: types.Integer<1>; fullkey: types.Text<1>; path: types.Text<1> }, "json_tree"> { return new runtime.Srf("json_tree", [this, arg0].filter((a) => a !== undefined), [["key", types.Any], ["value", types.Any], ["type", types.Text], ["atom", types.Any], ["id", types.Integer], ["parent", types.Integer], ["fullkey", types.Text], ["path", types.Text]]) as any; } + /** `->` — JSON subcomponent at path, as JSON text; NULL if absent. */ + @expose.unchecked() + ['->'] | string>(arg0: M0): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.opCall(runtime.sql`->`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `->>` — JSON subcomponent at path, as SQL value; NULL if absent. */ + @expose.unchecked() + ['->>'] | string>(arg0: M0): types.Any<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Any]]); return runtime.opCall(runtime.sql`->>`, [this, ...__rest] as [unknown, unknown], __rt) as any; } } diff --git a/src/types/sqlite/generated/bool.ts b/src/types/sqlite/generated/bool.ts new file mode 100644 index 00000000..265caf1a --- /dev/null +++ b/src/types/sqlite/generated/bool.ts @@ -0,0 +1,41 @@ +// Auto-generated by src/types/sqlite/emit.ts from docs/*.json — do not edit. +// Bool — the bool storage-class view: the __view brand +// (near-identical subclasses are otherwise structurally +// interchangeable, defeating nominal checks), [meta]/typname chrome, +// and the methods whose receiver domain is bool. Hand-written +// behavior (deserialize, acceptsPrimitive) extends this in +// ../overrides/bool.ts. +// Methods are placed by their receiver (first) argument's documented +// domain — runtime dispatch IS the type system for RPC callers +// (exoeval), so a value only carries the methods honest for its +// storage class. +// Every method: typed overload declarations over a runtime.match +// implementation (arg validation + primitive serialization + return +// class per matched overload — same dispatch model as PG). +import * as runtime from "../../runtime"; +import { meta } from "../../sql-value"; +import { expose } from "../../../exoeval/tool"; +import { Any } from "../overrides/any"; +import * as types from "../index"; + +export class Bool extends Any { + declare readonly __view: "bool"; + declare [meta]: { + __class: typeof types.Bool; + __raw: runtime.Sql; + __nullability: N; + __nullable: types.Bool<0 | 1>; + __nonNullable: types.Bool<1>; + __aggregate: types.Bool; + __any: types.Bool; + }; + static override __typname = runtime.sql`INTEGER`; + static override __typnameText = "bool"; + + /** `iif` — iif(C, T, F) — T when C is true, else F. */ + @expose.unchecked() + iif | number | string | boolean | Uint8Array, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Any<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Any, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Any]]); return runtime.funcCall("iif", [this, ...__rest], __rt) as any; } + /** `if` — Alias of iif() (3.48+). */ + @expose.unchecked() + if | number | string | boolean | Uint8Array, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Any<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Any, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Any]]); return runtime.funcCall("if", [this, ...__rest], __rt) as any; } +} diff --git a/src/types/sqlite/generated/integer.ts b/src/types/sqlite/generated/integer.ts index 7c211535..e0e807cb 100644 --- a/src/types/sqlite/generated/integer.ts +++ b/src/types/sqlite/generated/integer.ts @@ -1,488 +1,234 @@ -// Auto-generated by src/types/sqlite/generate.ts — do not edit. -// One method per (owner-type, function-name); same-type-args only. -// Heterogeneous overloads (e.g. substr) will be added via hand- -// curated overrides (Phase 1.4). -import { SqliteValue } from "../base"; -import { sql, type Sql } from "../../../builder/sql"; -import { meta } from "../../sql-value"; +// Auto-generated by src/types/sqlite/emit.ts from docs/*.json — do not edit. +// Integer — the integer storage-class view: the __view brand +// (near-identical subclasses are otherwise structurally +// interchangeable, defeating nominal checks), [meta]/typname chrome, +// and the methods whose receiver domain is integer. Hand-written +// behavior (deserialize, acceptsPrimitive) extends this in +// ../overrides/integer.ts. +// Methods are placed by their receiver (first) argument's documented +// domain — runtime dispatch IS the type system for RPC callers +// (exoeval), so a value only carries the methods honest for its +// storage class. +// Every method: typed overload declarations over a runtime.match +// implementation (arg validation + primitive serialization + return +// class per matched overload — same dispatch model as PG). import * as runtime from "../../runtime"; +import { meta } from "../../sql-value"; +import { expose } from "../../../exoeval/tool"; +import { Any } from "../overrides/any"; import * as types from "../index"; -export class Integer extends SqliteValue { +export class Integer extends Any { + declare readonly __view: "integer"; declare [meta]: { - __class: typeof Integer; - __raw: Sql; + __class: typeof types.Integer; + __raw: runtime.Sql; __nullability: N; - __nullable: Integer<0 | 1>; - __nonNullable: Integer<1>; - __aggregate: Integer; - __any: Integer; + __nullable: types.Integer<0 | 1>; + __nonNullable: types.Integer<1>; + __aggregate: types.Integer; + __any: types.Integer; }; - static override __typname = sql`INTEGER`; + static override __typname = runtime.sql`INTEGER`; static override __typnameText = "integer"; - abs(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("abs", [this, ...__rest], __rt) as types.Integer; - } - acos(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("acos", [this, ...__rest], __rt) as types.Real; - } - acosh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("acosh", [this, ...__rest], __rt) as types.Real; - } - asin(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("asin", [this, ...__rest], __rt) as types.Real; - } - asinh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("asinh", [this, ...__rest], __rt) as types.Real; - } - atan(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("atan", [this, ...__rest], __rt) as types.Real; - } - atan2 | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("atan2", [this, ...__rest], __rt) as types.Real>>; - } - atanh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("atanh", [this, ...__rest], __rt) as types.Real; - } - avg(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("avg", [this, ...__rest], __rt) as types.Real; - } - ceil(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("ceil", [this, ...__rest], __rt) as types.Integer; - } - ceiling(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("ceiling", [this, ...__rest], __rt) as types.Integer; - } - char(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("char", [this, ...__rest], __rt) as types.Text; - } - concat | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("concat", [this, ...__rest], __rt) as types.Text>>; - } - cos(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("cos", [this, ...__rest], __rt) as types.Real; - } - cosh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("cosh", [this, ...__rest], __rt) as types.Real; - } - count(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("count", [this, ...__rest], __rt) as types.Integer; - } - date(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("date", [this, ...__rest], __rt) as types.Text; - } - datetime(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("datetime", [this, ...__rest], __rt) as types.Text; - } - degrees(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("degrees", [this, ...__rest], __rt) as types.Real; - } - exp(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("exp", [this, ...__rest], __rt) as types.Real; - } - firstValue(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("first_value", [this, ...__rest], __rt) as types.Integer; - } - floor(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("floor", [this, ...__rest], __rt) as types.Integer; - } - format(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("format", [this, ...__rest], __rt) as types.Text; - } - fts5Insttoken(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("fts5_insttoken", [this, ...__rest], __rt) as types.Integer; - } - fts5Locale | number>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Blob]]); - return runtime.funcCall("fts5_locale", [this, ...__rest], __rt) as types.Blob>>; - } - glob | number>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("glob", [this, ...__rest], __rt) as types.Integer>>; - } - groupConcat(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("group_concat", [this, ...__rest], __rt) as types.Text; - } - hex(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("hex", [this, ...__rest], __rt) as types.Text; - } - ifnull | number>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("ifnull", [this, ...__rest], __rt) as types.Integer>>; - } - instr | number>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("instr", [this, ...__rest], __rt) as types.Integer>>; - } - json(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json", [this, ...__rest], __rt) as types.Text; - } - jsonArray(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_array", [this, ...__rest], __rt) as types.Text; - } - jsonArrayInsert(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_array_insert", [this, ...__rest], __rt) as types.Text; - } - jsonArrayLength(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_array_length", [this, ...__rest], __rt) as types.Integer; - } - jsonb(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb", [this, ...__rest], __rt) as types.Blob; - } - jsonbArray(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_array", [this, ...__rest], __rt) as types.Blob; - } - jsonbArrayInsert(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_array_insert", [this, ...__rest], __rt) as types.Blob; - } - jsonbGroupArray(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_group_array", [this, ...__rest], __rt) as types.Blob; - } - jsonbGroupObject | number>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Blob]]); - return runtime.funcCall("jsonb_group_object", [this, ...__rest], __rt) as types.Blob>>; - } - jsonbInsert(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_insert", [this, ...__rest], __rt) as types.Blob; - } - jsonbPatch | number>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Blob]]); - return runtime.funcCall("jsonb_patch", [this, ...__rest], __rt) as types.Blob>>; - } - jsonbRemove(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_remove", [this, ...__rest], __rt) as types.Blob; - } - jsonbReplace(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_replace", [this, ...__rest], __rt) as types.Blob; - } - jsonbSet(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_set", [this, ...__rest], __rt) as types.Blob; - } - jsonErrorPosition(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_error_position", [this, ...__rest], __rt) as types.Integer; - } - jsonGroupArray(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_group_array", [this, ...__rest], __rt) as types.Text; - } - jsonGroupObject | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("json_group_object", [this, ...__rest], __rt) as types.Text>>; - } - jsonInsert(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_insert", [this, ...__rest], __rt) as types.Text; - } - jsonPatch | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("json_patch", [this, ...__rest], __rt) as types.Text>>; - } - jsonPretty(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_pretty", [this, ...__rest], __rt) as types.Text; - } - jsonQuote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_quote", [this, ...__rest], __rt) as types.Text; - } - jsonRemove(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_remove", [this, ...__rest], __rt) as types.Text; - } - jsonReplace(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_replace", [this, ...__rest], __rt) as types.Text; - } - jsonSet(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_set", [this, ...__rest], __rt) as types.Text; - } - jsonType(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_type", [this, ...__rest], __rt) as types.Text; - } - jsonValid(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_valid", [this, ...__rest], __rt) as types.Integer; - } - julianday(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("julianday", [this, ...__rest], __rt) as types.Real; - } - lag | number, M1 extends types.Integer | number>(arg0: M0, arg1: M1): types.Integer | runtime.NullOf>> { - const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Integer, allowPrimitive: true }, { type: types.Integer, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("lag", [this, ...__rest], __rt) as types.Integer | runtime.NullOf>>; - } - lastValue(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("last_value", [this, ...__rest], __rt) as types.Integer; - } - lead | number, M1 extends types.Integer | number>(arg0: M0, arg1: M1): types.Integer | runtime.NullOf>> { - const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Integer, allowPrimitive: true }, { type: types.Integer, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("lead", [this, ...__rest], __rt) as types.Integer | runtime.NullOf>>; - } - length(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("length", [this, ...__rest], __rt) as types.Integer; - } - like | number>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("like", [this, ...__rest], __rt) as types.Integer>>; - } - likely(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("likely", [this, ...__rest], __rt) as types.Integer; - } - ln(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("ln", [this, ...__rest], __rt) as types.Real; - } - log(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("log", [this, ...__rest], __rt) as types.Real; - } - log10(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("log10", [this, ...__rest], __rt) as types.Real; - } - log2(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("log2", [this, ...__rest], __rt) as types.Real; - } - lower(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("lower", [this, ...__rest], __rt) as types.Text; - } - ltrim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("ltrim", [this, ...__rest], __rt) as types.Text; - } - max(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("max", [this, ...__rest], __rt) as types.Integer; - } - median(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("median", [this, ...__rest], __rt) as types.Real; - } - min(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("min", [this, ...__rest], __rt) as types.Integer; - } - mod | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("mod", [this, ...__rest], __rt) as types.Real>>; - } - nthValue | number>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("nth_value", [this, ...__rest], __rt) as types.Integer>>; - } - ntile(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("ntile", [this, ...__rest], __rt) as types.Integer; - } - octetLength(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("octet_length", [this, ...__rest], __rt) as types.Integer; - } - percentile | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("percentile", [this, ...__rest], __rt) as types.Real>>; - } - percentileCont | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("percentile_cont", [this, ...__rest], __rt) as types.Real>>; - } - percentileDisc | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("percentile_disc", [this, ...__rest], __rt) as types.Real>>; - } - pow | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("pow", [this, ...__rest], __rt) as types.Real>>; - } - power | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("power", [this, ...__rest], __rt) as types.Real>>; - } - printf(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("printf", [this, ...__rest], __rt) as types.Text; - } - quote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("quote", [this, ...__rest], __rt) as types.Text; - } - radians(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("radians", [this, ...__rest], __rt) as types.Real; - } - randomblob(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("randomblob", [this, ...__rest], __rt) as types.Blob; - } - replace | number, M1 extends types.Integer | number>(arg0: M0, arg1: M1): types.Text | runtime.NullOf>> { - const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Integer, allowPrimitive: true }, { type: types.Integer, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("replace", [this, ...__rest], __rt) as types.Text | runtime.NullOf>>; - } - round(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("round", [this, ...__rest], __rt) as types.Real; - } - rtrim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("rtrim", [this, ...__rest], __rt) as types.Text; - } - sign(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("sign", [this, ...__rest], __rt) as types.Integer; - } - sin(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("sin", [this, ...__rest], __rt) as types.Real; - } - sinh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("sinh", [this, ...__rest], __rt) as types.Real; - } - soundex(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("soundex", [this, ...__rest], __rt) as types.Text; - } - sqliteCompileoptionGet(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("sqlite_compileoption_get", [this, ...__rest], __rt) as types.Text; - } - sqliteCompileoptionUsed(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("sqlite_compileoption_used", [this, ...__rest], __rt) as types.Integer; - } - sqrt(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("sqrt", [this, ...__rest], __rt) as types.Real; - } - strftime(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("strftime", [this, ...__rest], __rt) as types.Text; - } - stringAgg | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("string_agg", [this, ...__rest], __rt) as types.Text>>; - } - substr | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("substr", [this, ...__rest], __rt) as types.Text>>; - } - substring | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("substring", [this, ...__rest], __rt) as types.Text>>; - } - subtype(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("subtype", [this, ...__rest], __rt) as types.Integer; - } - sum(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("sum", [this, ...__rest], __rt) as types.Integer; - } - tan(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("tan", [this, ...__rest], __rt) as types.Real; - } - tanh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("tanh", [this, ...__rest], __rt) as types.Real; - } - time(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("time", [this, ...__rest], __rt) as types.Text; - } - timediff | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("timediff", [this, ...__rest], __rt) as types.Text>>; - } - total(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("total", [this, ...__rest], __rt) as types.Real; - } - trim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("trim", [this, ...__rest], __rt) as types.Text; - } - trunc(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("trunc", [this, ...__rest], __rt) as types.Integer; - } - typeof(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("typeof", [this, ...__rest], __rt) as types.Text; - } - unicode(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("unicode", [this, ...__rest], __rt) as types.Integer; - } - unistr(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("unistr", [this, ...__rest], __rt) as types.Text; - } - unistrQuote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("unistr_quote", [this, ...__rest], __rt) as types.Text; - } - unixepoch(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("unixepoch", [this, ...__rest], __rt) as types.Integer; - } - unlikely(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("unlikely", [this, ...__rest], __rt) as types.Integer; - } - upper(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("upper", [this, ...__rest], __rt) as types.Text; - } - zeroblob(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("zeroblob", [this, ...__rest], __rt) as types.Blob; - } + /** `abs` — Absolute value. INTEGER in → INTEGER out; throws on INT64_MIN. */ + @expose.unchecked() + abs(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("abs", [this, ...__rest], __rt) as any; } + /** `char` — String from unicode code points. */ + @expose.unchecked() + char(...rest: (types.Integer | number)[]): types.Text<1> { const [__rt, ...__rest] = runtime.match([...rest], [[[{ type: types.Integer, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("char", [this, ...__rest], __rt) as any; } + /** `round` — Round to Y digits (default 0). Result is REAL. */ + round | number>(arg0?: M0): types.Real>>; + @expose.unchecked() + round(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Real], [[{ type: types.Integer, allowPrimitive: true }], types.Real]]); return runtime.funcCall("round", [this, ...__rest], __rt) as any; } + /** `sign` — -1, 0, or +1; NULL for non-numeric. */ + @expose.unchecked() + sign(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("sign", [this, ...__rest], __rt) as any; } + /** `zeroblob` — BLOB of N zero bytes. */ + @expose.unchecked() + zeroblob(): types.Blob<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); return runtime.funcCall("zeroblob", [this, ...__rest], __rt) as any; } + /** `acos` — Arccosine in radians. */ + @expose.unchecked() + acos(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("acos", [this, ...__rest], __rt) as any; } + /** `acosh` — Inverse hyperbolic cosine. */ + @expose.unchecked() + acosh(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("acosh", [this, ...__rest], __rt) as any; } + /** `asin` — Arcsine in radians. */ + @expose.unchecked() + asin(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("asin", [this, ...__rest], __rt) as any; } + /** `asinh` — Inverse hyperbolic sine. */ + @expose.unchecked() + asinh(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("asinh", [this, ...__rest], __rt) as any; } + /** `atan` — Arctangent in radians. */ + @expose.unchecked() + atan(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("atan", [this, ...__rest], __rt) as any; } + /** `atan2` — atan2(Y, X) — arctangent of Y/X in radians. */ + atan2>(arg0: M0): types.Real>>; + /** `atan2` — atan2(Y, X) — arctangent of Y/X in radians. */ + atan2 | number>(arg0: M0): types.Real>>; + @expose.unchecked() + atan2(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer }], types.Real], [[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("atan2", [this, ...__rest], __rt) as any; } + /** `atanh` — Inverse hyperbolic tangent. */ + @expose.unchecked() + atanh(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("atanh", [this, ...__rest], __rt) as any; } + /** `ceil` — Smallest integer ≥ X. */ + @expose.unchecked() + ceil(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("ceil", [this, ...__rest], __rt) as any; } + /** `ceiling` — Alias of ceil(). */ + @expose.unchecked() + ceiling(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("ceiling", [this, ...__rest], __rt) as any; } + /** `cos` — Cosine of X (radians). */ + @expose.unchecked() + cos(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("cos", [this, ...__rest], __rt) as any; } + /** `cosh` — Hyperbolic cosine. */ + @expose.unchecked() + cosh(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("cosh", [this, ...__rest], __rt) as any; } + /** `degrees` — Radians → degrees. */ + @expose.unchecked() + degrees(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("degrees", [this, ...__rest], __rt) as any; } + /** `exp` — e raised to X. */ + @expose.unchecked() + exp(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("exp", [this, ...__rest], __rt) as any; } + /** `floor` — Largest integer ≤ X. */ + @expose.unchecked() + floor(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("floor", [this, ...__rest], __rt) as any; } + /** `ln` — Natural logarithm; NULL for X ≤ 0. */ + @expose.unchecked() + ln(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("ln", [this, ...__rest], __rt) as any; } + /** `log` — log(X) base-10 log; log(B, X) base-B log. NULL for non-positive X. */ + log(): types.Real<0 | 1>; + /** `log` — log(X) base-10 log; log(B, X) base-B log. NULL for non-positive X. */ + log | number>(arg0: M0): types.Real<0 | 1>; + @expose.unchecked() + log(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Real], [[{ type: types.Integer, allowPrimitive: true }], types.Real]]); return runtime.funcCall("log", [this, ...__rest], __rt) as any; } + /** `log10` — Base-10 logarithm; NULL for X ≤ 0. */ + @expose.unchecked() + log10(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("log10", [this, ...__rest], __rt) as any; } + /** `log2` — Base-2 logarithm; NULL for X ≤ 0. */ + @expose.unchecked() + log2(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("log2", [this, ...__rest], __rt) as any; } + /** `mod` — mod(X, Y) — remainder of X/Y (C fmod semantics; result is REAL). */ + mod>(arg0: M0): types.Real<0 | 1>; + /** `mod` — mod(X, Y) — remainder of X/Y (C fmod semantics; result is REAL). */ + mod | number>(arg0: M0): types.Real<0 | 1>; + @expose.unchecked() + mod(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer }], types.Real], [[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("mod", [this, ...__rest], __rt) as any; } + /** `pow` — pow(X, Y) — X raised to Y. */ + pow>(arg0: M0): types.Real<0 | 1>; + /** `pow` — pow(X, Y) — X raised to Y. */ + pow | number>(arg0: M0): types.Real<0 | 1>; + @expose.unchecked() + pow(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer }], types.Real], [[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("pow", [this, ...__rest], __rt) as any; } + /** `power` — Alias of pow(). */ + @expose.unchecked() + power | number>(arg0: M0): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Real]]); return runtime.funcCall("power", [this, ...__rest], __rt) as any; } + /** `radians` — Degrees → radians. */ + @expose.unchecked() + radians(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("radians", [this, ...__rest], __rt) as any; } + /** `sin` — Sine of X (radians). */ + @expose.unchecked() + sin(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("sin", [this, ...__rest], __rt) as any; } + /** `sinh` — Hyperbolic sine. */ + @expose.unchecked() + sinh(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("sinh", [this, ...__rest], __rt) as any; } + /** `sqrt` — Square root; NULL for X < 0. */ + @expose.unchecked() + sqrt(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("sqrt", [this, ...__rest], __rt) as any; } + /** `tan` — Tangent of X (radians). */ + @expose.unchecked() + tan(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("tan", [this, ...__rest], __rt) as any; } + /** `tanh` — Hyperbolic tangent. */ + @expose.unchecked() + tanh(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("tanh", [this, ...__rest], __rt) as any; } + /** `trunc` — Truncate toward zero. */ + @expose.unchecked() + trunc(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("trunc", [this, ...__rest], __rt) as any; } + /** `sum` — Sum; NULL over the empty set; integer overflow throws. */ + @expose.unchecked() + sum(): types.Integer<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("sum", [this, ...__rest], __rt) as any; } + /** `median` — Median (percentile extension). Numeric inputs only. */ + @expose.unchecked() + median(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("median", [this, ...__rest], __rt) as any; } + /** `percentile` — P-th percentile, P in 0..100 (percentile extension). */ + @expose.unchecked() + percentile | number>(arg0: M0): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("percentile", [this, ...__rest], __rt) as any; } + /** `percentile_cont` — Continuous percentile, fraction in 0..1. */ + @expose.unchecked() + percentileCont | number>(arg0: M0): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("percentile_cont", [this, ...__rest], __rt) as any; } + /** `percentile_disc` — Discrete percentile, fraction in 0..1. */ + @expose.unchecked() + percentileDisc | number>(arg0: M0): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("percentile_disc", [this, ...__rest], __rt) as any; } + /** `+` — Addition. */ + ['+'] | number>(arg0: M0): types.Integer>>; + /** `+` — Addition. */ + ['+']>(arg0: M0): types.Real>>; + @expose.unchecked() + ['+'](arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer], [[{ type: types.Real }], types.Real]]); return runtime.opCall(runtime.sql`+`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `+` — Addition. */ + plus | number>(arg0: M0): types.Integer>>; + /** `+` — Addition. */ + plus>(arg0: M0): types.Real>>; + @expose.unchecked() + plus(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer], [[{ type: types.Real }], types.Real]]); return runtime.opCall(runtime.sql`+`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `-` — Subtraction. */ + ['-'] | number>(arg0: M0): types.Integer>>; + /** `-` — Subtraction. */ + ['-']>(arg0: M0): types.Real>>; + @expose.unchecked() + ['-'](arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer], [[{ type: types.Real }], types.Real]]); return runtime.opCall(runtime.sql`-`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `-` — Subtraction. */ + minus | number>(arg0: M0): types.Integer>>; + /** `-` — Subtraction. */ + minus>(arg0: M0): types.Real>>; + @expose.unchecked() + minus(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer], [[{ type: types.Real }], types.Real]]); return runtime.opCall(runtime.sql`-`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `*` — Multiplication. */ + ['*'] | number>(arg0: M0): types.Integer>>; + /** `*` — Multiplication. */ + ['*']>(arg0: M0): types.Real>>; + @expose.unchecked() + ['*'](arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer], [[{ type: types.Real }], types.Real]]); return runtime.opCall(runtime.sql`*`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `*` — Multiplication. */ + times | number>(arg0: M0): types.Integer>>; + /** `*` — Multiplication. */ + times>(arg0: M0): types.Real>>; + @expose.unchecked() + times(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer], [[{ type: types.Real }], types.Real]]); return runtime.opCall(runtime.sql`*`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `/` — Division — INTEGER/INTEGER truncates; ÷0 → NULL. */ + ['/'] | number>(arg0: M0): types.Integer<0 | 1>; + /** `/` — Division — INTEGER/INTEGER truncates; ÷0 → NULL. */ + ['/']>(arg0: M0): types.Real<0 | 1>; + @expose.unchecked() + ['/'](arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer], [[{ type: types.Real }], types.Real]]); return runtime.opCall(runtime.sql`/`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `/` — Division — INTEGER/INTEGER truncates; ÷0 → NULL. */ + divide | number>(arg0: M0): types.Integer<0 | 1>; + /** `/` — Division — INTEGER/INTEGER truncates; ÷0 → NULL. */ + divide>(arg0: M0): types.Real<0 | 1>; + @expose.unchecked() + divide(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer], [[{ type: types.Real }], types.Real]]); return runtime.opCall(runtime.sql`/`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `%` — Remainder (integer semantics) — %0 → NULL. */ + @expose.unchecked() + ['%'] | number>(arg0: M0): types.Integer<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer]]); return runtime.opCall(runtime.sql`%`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `&` — Bitwise AND (operands coerced to INTEGER). */ + @expose.unchecked() + ['&'] | number>(arg0: M0): types.Integer>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer]]); return runtime.opCall(runtime.sql`&`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `|` — Bitwise OR. */ + @expose.unchecked() + ['|'] | number>(arg0: M0): types.Integer>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer]]); return runtime.opCall(runtime.sql`|`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `<<` — Left shift. */ + @expose.unchecked() + ['<<'] | number>(arg0: M0): types.Integer>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer]]); return runtime.opCall(runtime.sql`<<`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `>>` — Right shift. */ + @expose.unchecked() + ['>>'] | number>(arg0: M0): types.Integer>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Integer, allowPrimitive: true }], types.Integer]]); return runtime.opCall(runtime.sql`>>`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `-` — Arithmetic negation. */ + @expose.unchecked() + negate(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.unaryOpCall(runtime.sql`-`, this, __rt) as any; } + /** `~` — Bitwise NOT (operand coerced to INTEGER). */ + @expose.unchecked() + ['~'](): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.unaryOpCall(runtime.sql`~`, this, __rt) as any; } + /** `~` — Bitwise NOT (operand coerced to INTEGER). */ + @expose.unchecked() + bitNot(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.unaryOpCall(runtime.sql`~`, this, __rt) as any; } } diff --git a/src/types/sqlite/generated/real.ts b/src/types/sqlite/generated/real.ts index 72eac897..99cc9a9b 100644 --- a/src/types/sqlite/generated/real.ts +++ b/src/types/sqlite/generated/real.ts @@ -1,464 +1,210 @@ -// Auto-generated by src/types/sqlite/generate.ts — do not edit. -// One method per (owner-type, function-name); same-type-args only. -// Heterogeneous overloads (e.g. substr) will be added via hand- -// curated overrides (Phase 1.4). -import { SqliteValue } from "../base"; -import { sql, type Sql } from "../../../builder/sql"; -import { meta } from "../../sql-value"; +// Auto-generated by src/types/sqlite/emit.ts from docs/*.json — do not edit. +// Real — the real storage-class view: the __view brand +// (near-identical subclasses are otherwise structurally +// interchangeable, defeating nominal checks), [meta]/typname chrome, +// and the methods whose receiver domain is real. Hand-written +// behavior (deserialize, acceptsPrimitive) extends this in +// ../overrides/real.ts. +// Methods are placed by their receiver (first) argument's documented +// domain — runtime dispatch IS the type system for RPC callers +// (exoeval), so a value only carries the methods honest for its +// storage class. +// Every method: typed overload declarations over a runtime.match +// implementation (arg validation + primitive serialization + return +// class per matched overload — same dispatch model as PG). import * as runtime from "../../runtime"; +import { meta } from "../../sql-value"; +import { expose } from "../../../exoeval/tool"; +import { Any } from "../overrides/any"; import * as types from "../index"; -export class Real extends SqliteValue { +export class Real extends Any { + declare readonly __view: "real"; declare [meta]: { - __class: typeof Real; - __raw: Sql; + __class: typeof types.Real; + __raw: runtime.Sql; __nullability: N; - __nullable: Real<0 | 1>; - __nonNullable: Real<1>; - __aggregate: Real; - __any: Real; + __nullable: types.Real<0 | 1>; + __nonNullable: types.Real<1>; + __aggregate: types.Real; + __any: types.Real; }; - static override __typname = sql`REAL`; + static override __typname = runtime.sql`REAL`; static override __typnameText = "real"; - abs(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("abs", [this, ...__rest], __rt) as types.Real; - } - acosh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("acosh", [this, ...__rest], __rt) as types.Real; - } - asinh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("asinh", [this, ...__rest], __rt) as types.Real; - } - atan(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("atan", [this, ...__rest], __rt) as types.Real; - } - atan2 | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("atan2", [this, ...__rest], __rt) as types.Real>>; - } - avg(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("avg", [this, ...__rest], __rt) as types.Real; - } - ceil(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("ceil", [this, ...__rest], __rt) as types.Real; - } - ceiling(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("ceiling", [this, ...__rest], __rt) as types.Real; - } - char(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("char", [this, ...__rest], __rt) as types.Text; - } - concat | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("concat", [this, ...__rest], __rt) as types.Text>>; - } - cos(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("cos", [this, ...__rest], __rt) as types.Real; - } - cosh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("cosh", [this, ...__rest], __rt) as types.Real; - } - count(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("count", [this, ...__rest], __rt) as types.Integer; - } - date(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("date", [this, ...__rest], __rt) as types.Text; - } - datetime(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("datetime", [this, ...__rest], __rt) as types.Text; - } - degrees(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("degrees", [this, ...__rest], __rt) as types.Real; - } - exp(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("exp", [this, ...__rest], __rt) as types.Real; - } - firstValue(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("first_value", [this, ...__rest], __rt) as types.Real; - } - floor(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("floor", [this, ...__rest], __rt) as types.Real; - } - format(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("format", [this, ...__rest], __rt) as types.Text; - } - fts5Insttoken(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("fts5_insttoken", [this, ...__rest], __rt) as types.Real; - } - fts5Locale | number>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Blob]]); - return runtime.funcCall("fts5_locale", [this, ...__rest], __rt) as types.Blob>>; - } - glob | number>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("glob", [this, ...__rest], __rt) as types.Integer>>; - } - groupConcat(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("group_concat", [this, ...__rest], __rt) as types.Text; - } - hex(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("hex", [this, ...__rest], __rt) as types.Text; - } - ifnull | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("ifnull", [this, ...__rest], __rt) as types.Real>>; - } - instr | number>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("instr", [this, ...__rest], __rt) as types.Integer>>; - } - json(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json", [this, ...__rest], __rt) as types.Text; - } - jsonArray(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_array", [this, ...__rest], __rt) as types.Text; - } - jsonArrayInsert(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_array_insert", [this, ...__rest], __rt) as types.Text; - } - jsonArrayLength(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_array_length", [this, ...__rest], __rt) as types.Integer; - } - jsonb(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb", [this, ...__rest], __rt) as types.Blob; - } - jsonbArray(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_array", [this, ...__rest], __rt) as types.Blob; - } - jsonbArrayInsert(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_array_insert", [this, ...__rest], __rt) as types.Blob; - } - jsonbGroupArray(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_group_array", [this, ...__rest], __rt) as types.Blob; - } - jsonbGroupObject | number>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Blob]]); - return runtime.funcCall("jsonb_group_object", [this, ...__rest], __rt) as types.Blob>>; - } - jsonbInsert(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_insert", [this, ...__rest], __rt) as types.Blob; - } - jsonbPatch | number>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Blob]]); - return runtime.funcCall("jsonb_patch", [this, ...__rest], __rt) as types.Blob>>; - } - jsonbRemove(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_remove", [this, ...__rest], __rt) as types.Blob; - } - jsonbReplace(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_replace", [this, ...__rest], __rt) as types.Blob; - } - jsonbSet(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_set", [this, ...__rest], __rt) as types.Blob; - } - jsonErrorPosition(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_error_position", [this, ...__rest], __rt) as types.Integer; - } - jsonGroupArray(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_group_array", [this, ...__rest], __rt) as types.Text; - } - jsonGroupObject | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("json_group_object", [this, ...__rest], __rt) as types.Text>>; - } - jsonInsert(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_insert", [this, ...__rest], __rt) as types.Text; - } - jsonPatch | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("json_patch", [this, ...__rest], __rt) as types.Text>>; - } - jsonPretty(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_pretty", [this, ...__rest], __rt) as types.Text; - } - jsonQuote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_quote", [this, ...__rest], __rt) as types.Text; - } - jsonRemove(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_remove", [this, ...__rest], __rt) as types.Text; - } - jsonReplace(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_replace", [this, ...__rest], __rt) as types.Text; - } - jsonSet(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_set", [this, ...__rest], __rt) as types.Text; - } - jsonType(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_type", [this, ...__rest], __rt) as types.Text; - } - jsonValid(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_valid", [this, ...__rest], __rt) as types.Integer; - } - julianday(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("julianday", [this, ...__rest], __rt) as types.Real; - } - lag | number, M1 extends types.Real | number>(arg0: M0, arg1: M1): types.Real | runtime.NullOf>> { - const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Real, allowPrimitive: true }, { type: types.Real, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("lag", [this, ...__rest], __rt) as types.Real | runtime.NullOf>>; - } - lastValue(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("last_value", [this, ...__rest], __rt) as types.Real; - } - lead | number, M1 extends types.Real | number>(arg0: M0, arg1: M1): types.Real | runtime.NullOf>> { - const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Real, allowPrimitive: true }, { type: types.Real, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("lead", [this, ...__rest], __rt) as types.Real | runtime.NullOf>>; - } - length(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("length", [this, ...__rest], __rt) as types.Integer; - } - like | number>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("like", [this, ...__rest], __rt) as types.Integer>>; - } - likely(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("likely", [this, ...__rest], __rt) as types.Real; - } - ln(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("ln", [this, ...__rest], __rt) as types.Real; - } - log(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("log", [this, ...__rest], __rt) as types.Real; - } - log10(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("log10", [this, ...__rest], __rt) as types.Real; - } - log2(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("log2", [this, ...__rest], __rt) as types.Real; - } - lower(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("lower", [this, ...__rest], __rt) as types.Text; - } - ltrim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("ltrim", [this, ...__rest], __rt) as types.Text; - } - max(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("max", [this, ...__rest], __rt) as types.Real; - } - median(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("median", [this, ...__rest], __rt) as types.Real; - } - min(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("min", [this, ...__rest], __rt) as types.Real; - } - mod | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("mod", [this, ...__rest], __rt) as types.Real>>; - } - ntile(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("ntile", [this, ...__rest], __rt) as types.Integer; - } - octetLength(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("octet_length", [this, ...__rest], __rt) as types.Integer; - } - percentile | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("percentile", [this, ...__rest], __rt) as types.Real>>; - } - pow | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("pow", [this, ...__rest], __rt) as types.Real>>; - } - power | number>(arg0: M0): types.Real>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); - return runtime.funcCall("power", [this, ...__rest], __rt) as types.Real>>; - } - printf(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("printf", [this, ...__rest], __rt) as types.Text; - } - quote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("quote", [this, ...__rest], __rt) as types.Text; - } - radians(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("radians", [this, ...__rest], __rt) as types.Real; - } - randomblob(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("randomblob", [this, ...__rest], __rt) as types.Blob; - } - replace | number, M1 extends types.Real | number>(arg0: M0, arg1: M1): types.Text | runtime.NullOf>> { - const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Real, allowPrimitive: true }, { type: types.Real, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("replace", [this, ...__rest], __rt) as types.Text | runtime.NullOf>>; - } - round(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("round", [this, ...__rest], __rt) as types.Real; - } - rtrim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("rtrim", [this, ...__rest], __rt) as types.Text; - } - sign(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("sign", [this, ...__rest], __rt) as types.Integer; - } - sin(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("sin", [this, ...__rest], __rt) as types.Real; - } - sinh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("sinh", [this, ...__rest], __rt) as types.Real; - } - soundex(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("soundex", [this, ...__rest], __rt) as types.Text; - } - sqliteCompileoptionGet(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("sqlite_compileoption_get", [this, ...__rest], __rt) as types.Text; - } - sqliteCompileoptionUsed(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("sqlite_compileoption_used", [this, ...__rest], __rt) as types.Integer; - } - sqrt(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("sqrt", [this, ...__rest], __rt) as types.Real; - } - strftime(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("strftime", [this, ...__rest], __rt) as types.Text; - } - stringAgg | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("string_agg", [this, ...__rest], __rt) as types.Text>>; - } - substr | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("substr", [this, ...__rest], __rt) as types.Text>>; - } - substring | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("substring", [this, ...__rest], __rt) as types.Text>>; - } - subtype(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("subtype", [this, ...__rest], __rt) as types.Integer; - } - sum(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("sum", [this, ...__rest], __rt) as types.Real; - } - tan(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("tan", [this, ...__rest], __rt) as types.Real; - } - tanh(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("tanh", [this, ...__rest], __rt) as types.Real; - } - time(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("time", [this, ...__rest], __rt) as types.Text; - } - timediff | number>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("timediff", [this, ...__rest], __rt) as types.Text>>; - } - total(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("total", [this, ...__rest], __rt) as types.Real; - } - trim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("trim", [this, ...__rest], __rt) as types.Text; - } - trunc(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("trunc", [this, ...__rest], __rt) as types.Real; - } - typeof(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("typeof", [this, ...__rest], __rt) as types.Text; - } - unicode(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("unicode", [this, ...__rest], __rt) as types.Integer; - } - unistr(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("unistr", [this, ...__rest], __rt) as types.Text; - } - unistrQuote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("unistr_quote", [this, ...__rest], __rt) as types.Text; - } - unixepoch(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("unixepoch", [this, ...__rest], __rt) as types.Integer; - } - unlikely(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("unlikely", [this, ...__rest], __rt) as types.Real; - } - upper(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("upper", [this, ...__rest], __rt) as types.Text; - } - zeroblob(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("zeroblob", [this, ...__rest], __rt) as types.Blob; - } + /** `abs` — Absolute value. INTEGER in → INTEGER out; throws on INT64_MIN. */ + @expose.unchecked() + abs(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("abs", [this, ...__rest], __rt) as any; } + /** `round` — Round to Y digits (default 0). Result is REAL. */ + round | number>(arg0?: M0): types.Real>>; + @expose.unchecked() + round(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Real], [[{ type: types.Integer, allowPrimitive: true }], types.Real]]); return runtime.funcCall("round", [this, ...__rest], __rt) as any; } + /** `sign` — -1, 0, or +1; NULL for non-numeric. */ + @expose.unchecked() + sign(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("sign", [this, ...__rest], __rt) as any; } + /** `acos` — Arccosine in radians. */ + @expose.unchecked() + acos(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("acos", [this, ...__rest], __rt) as any; } + /** `acosh` — Inverse hyperbolic cosine. */ + @expose.unchecked() + acosh(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("acosh", [this, ...__rest], __rt) as any; } + /** `asin` — Arcsine in radians. */ + @expose.unchecked() + asin(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("asin", [this, ...__rest], __rt) as any; } + /** `asinh` — Inverse hyperbolic sine. */ + @expose.unchecked() + asinh(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("asinh", [this, ...__rest], __rt) as any; } + /** `atan` — Arctangent in radians. */ + @expose.unchecked() + atan(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("atan", [this, ...__rest], __rt) as any; } + /** `atan2` — atan2(Y, X) — arctangent of Y/X in radians. */ + atan2 | number>(arg0: M0): types.Real>>; + /** `atan2` — atan2(Y, X) — arctangent of Y/X in radians. */ + atan2>(arg0: M0): types.Real>>; + @expose.unchecked() + atan2(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.funcCall("atan2", [this, ...__rest], __rt) as any; } + /** `atanh` — Inverse hyperbolic tangent. */ + @expose.unchecked() + atanh(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("atanh", [this, ...__rest], __rt) as any; } + /** `ceil` — Smallest integer ≥ X. */ + @expose.unchecked() + ceil(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("ceil", [this, ...__rest], __rt) as any; } + /** `ceiling` — Alias of ceil(). */ + @expose.unchecked() + ceiling(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("ceiling", [this, ...__rest], __rt) as any; } + /** `cos` — Cosine of X (radians). */ + @expose.unchecked() + cos(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("cos", [this, ...__rest], __rt) as any; } + /** `cosh` — Hyperbolic cosine. */ + @expose.unchecked() + cosh(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("cosh", [this, ...__rest], __rt) as any; } + /** `degrees` — Radians → degrees. */ + @expose.unchecked() + degrees(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("degrees", [this, ...__rest], __rt) as any; } + /** `exp` — e raised to X. */ + @expose.unchecked() + exp(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("exp", [this, ...__rest], __rt) as any; } + /** `floor` — Largest integer ≤ X. */ + @expose.unchecked() + floor(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("floor", [this, ...__rest], __rt) as any; } + /** `ln` — Natural logarithm; NULL for X ≤ 0. */ + @expose.unchecked() + ln(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("ln", [this, ...__rest], __rt) as any; } + /** `log` — log(X) base-10 log; log(B, X) base-B log. NULL for non-positive X. */ + log(): types.Real<0 | 1>; + /** `log` — log(X) base-10 log; log(B, X) base-B log. NULL for non-positive X. */ + log | number>(arg0: M0): types.Real<0 | 1>; + @expose.unchecked() + log(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Real], [[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("log", [this, ...__rest], __rt) as any; } + /** `log10` — Base-10 logarithm; NULL for X ≤ 0. */ + @expose.unchecked() + log10(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("log10", [this, ...__rest], __rt) as any; } + /** `log2` — Base-2 logarithm; NULL for X ≤ 0. */ + @expose.unchecked() + log2(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("log2", [this, ...__rest], __rt) as any; } + /** `mod` — mod(X, Y) — remainder of X/Y (C fmod semantics; result is REAL). */ + mod | number>(arg0: M0): types.Real<0 | 1>; + /** `mod` — mod(X, Y) — remainder of X/Y (C fmod semantics; result is REAL). */ + mod>(arg0: M0): types.Real<0 | 1>; + @expose.unchecked() + mod(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.funcCall("mod", [this, ...__rest], __rt) as any; } + /** `pow` — pow(X, Y) — X raised to Y. */ + pow | number>(arg0: M0): types.Real<0 | 1>; + /** `pow` — pow(X, Y) — X raised to Y. */ + pow>(arg0: M0): types.Real<0 | 1>; + @expose.unchecked() + pow(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.funcCall("pow", [this, ...__rest], __rt) as any; } + /** `power` — Alias of pow(). */ + @expose.unchecked() + power | number>(arg0: M0): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("power", [this, ...__rest], __rt) as any; } + /** `radians` — Degrees → radians. */ + @expose.unchecked() + radians(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("radians", [this, ...__rest], __rt) as any; } + /** `sin` — Sine of X (radians). */ + @expose.unchecked() + sin(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("sin", [this, ...__rest], __rt) as any; } + /** `sinh` — Hyperbolic sine. */ + @expose.unchecked() + sinh(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("sinh", [this, ...__rest], __rt) as any; } + /** `sqrt` — Square root; NULL for X < 0. */ + @expose.unchecked() + sqrt(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("sqrt", [this, ...__rest], __rt) as any; } + /** `tan` — Tangent of X (radians). */ + @expose.unchecked() + tan(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("tan", [this, ...__rest], __rt) as any; } + /** `tanh` — Hyperbolic tangent. */ + @expose.unchecked() + tanh(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("tanh", [this, ...__rest], __rt) as any; } + /** `trunc` — Truncate toward zero. */ + @expose.unchecked() + trunc(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("trunc", [this, ...__rest], __rt) as any; } + /** `sum` — Sum; NULL over the empty set; integer overflow throws. */ + @expose.unchecked() + sum(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("sum", [this, ...__rest], __rt) as any; } + /** `median` — Median (percentile extension). Numeric inputs only. */ + @expose.unchecked() + median(): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.funcCall("median", [this, ...__rest], __rt) as any; } + /** `percentile` — P-th percentile, P in 0..100 (percentile extension). */ + @expose.unchecked() + percentile | number>(arg0: M0): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("percentile", [this, ...__rest], __rt) as any; } + /** `percentile_cont` — Continuous percentile, fraction in 0..1. */ + @expose.unchecked() + percentileCont | number>(arg0: M0): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("percentile_cont", [this, ...__rest], __rt) as any; } + /** `percentile_disc` — Discrete percentile, fraction in 0..1. */ + @expose.unchecked() + percentileDisc | number>(arg0: M0): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.funcCall("percentile_disc", [this, ...__rest], __rt) as any; } + /** `+` — Addition. */ + ['+'] | number>(arg0: M0): types.Real>>; + /** `+` — Addition. */ + ['+']>(arg0: M0): types.Real>>; + @expose.unchecked() + ['+'](arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.opCall(runtime.sql`+`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `+` — Addition. */ + plus | number>(arg0: M0): types.Real>>; + /** `+` — Addition. */ + plus>(arg0: M0): types.Real>>; + @expose.unchecked() + plus(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.opCall(runtime.sql`+`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `-` — Subtraction. */ + ['-'] | number>(arg0: M0): types.Real>>; + /** `-` — Subtraction. */ + ['-']>(arg0: M0): types.Real>>; + @expose.unchecked() + ['-'](arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.opCall(runtime.sql`-`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `-` — Subtraction. */ + minus | number>(arg0: M0): types.Real>>; + /** `-` — Subtraction. */ + minus>(arg0: M0): types.Real>>; + @expose.unchecked() + minus(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.opCall(runtime.sql`-`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `*` — Multiplication. */ + ['*'] | number>(arg0: M0): types.Real>>; + /** `*` — Multiplication. */ + ['*']>(arg0: M0): types.Real>>; + @expose.unchecked() + ['*'](arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.opCall(runtime.sql`*`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `*` — Multiplication. */ + times | number>(arg0: M0): types.Real>>; + /** `*` — Multiplication. */ + times>(arg0: M0): types.Real>>; + @expose.unchecked() + times(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.opCall(runtime.sql`*`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `/` — Division — INTEGER/INTEGER truncates; ÷0 → NULL. */ + ['/'] | number>(arg0: M0): types.Real<0 | 1>; + /** `/` — Division — INTEGER/INTEGER truncates; ÷0 → NULL. */ + ['/']>(arg0: M0): types.Real<0 | 1>; + @expose.unchecked() + ['/'](arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.opCall(runtime.sql`/`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `/` — Division — INTEGER/INTEGER truncates; ÷0 → NULL. */ + divide | number>(arg0: M0): types.Real<0 | 1>; + /** `/` — Division — INTEGER/INTEGER truncates; ÷0 → NULL. */ + divide>(arg0: M0): types.Real<0 | 1>; + @expose.unchecked() + divide(arg0: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real], [[{ type: types.Integer }], types.Real]]); return runtime.opCall(runtime.sql`/`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `%` — Remainder (integer semantics) — %0 → NULL. */ + @expose.unchecked() + ['%'] | number>(arg0: M0): types.Real<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Real, allowPrimitive: true }], types.Real]]); return runtime.opCall(runtime.sql`%`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `-` — Arithmetic negation. */ + @expose.unchecked() + negate(): types.Real { const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); return runtime.unaryOpCall(runtime.sql`-`, this, __rt) as any; } } diff --git a/src/types/sqlite/generated/text.ts b/src/types/sqlite/generated/text.ts index 7a0208c7..96c6d128 100644 --- a/src/types/sqlite/generated/text.ts +++ b/src/types/sqlite/generated/text.ts @@ -1,273 +1,195 @@ -// Auto-generated by src/types/sqlite/generate.ts — do not edit. -// One method per (owner-type, function-name); same-type-args only. -// Heterogeneous overloads (e.g. substr) will be added via hand- -// curated overrides (Phase 1.4). -import { SqliteValue } from "../base"; -import { sql, type Sql } from "../../../builder/sql"; -import { meta } from "../../sql-value"; +// Auto-generated by src/types/sqlite/emit.ts from docs/*.json — do not edit. +// Text — the text storage-class view: the __view brand +// (near-identical subclasses are otherwise structurally +// interchangeable, defeating nominal checks), [meta]/typname chrome, +// and the methods whose receiver domain is text. Hand-written +// behavior (deserialize, acceptsPrimitive) extends this in +// ../overrides/text.ts. +// Methods are placed by their receiver (first) argument's documented +// domain — runtime dispatch IS the type system for RPC callers +// (exoeval), so a value only carries the methods honest for its +// storage class. +// Every method: typed overload declarations over a runtime.match +// implementation (arg validation + primitive serialization + return +// class per matched overload — same dispatch model as PG). import * as runtime from "../../runtime"; +import { meta } from "../../sql-value"; +import { expose } from "../../../exoeval/tool"; +import { Any } from "../overrides/any"; import * as types from "../index"; -export class Text extends SqliteValue { +export class Text extends Any { + declare readonly __view: "text"; declare [meta]: { - __class: typeof Text; - __raw: Sql; + __class: typeof types.Text; + __raw: runtime.Sql; __nullability: N; - __nullable: Text<0 | 1>; - __nonNullable: Text<1>; - __aggregate: Text; - __any: Text; + __nullable: types.Text<0 | 1>; + __nonNullable: types.Text<1>; + __aggregate: types.Text; + __any: types.Text; }; - static override __typname = sql`TEXT`; + static override __typname = runtime.sql`TEXT`; static override __typnameText = "text"; - declare deserialize: (raw: string) => string; - abs(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("abs", [this, ...__rest], __rt) as types.Real; - } - avg(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("avg", [this, ...__rest], __rt) as types.Real; - } - char(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("char", [this, ...__rest], __rt) as types.Text; - } - concat | string>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("concat", [this, ...__rest], __rt) as types.Text>>; - } - count(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("count", [this, ...__rest], __rt) as types.Integer; - } - firstValue(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("first_value", [this, ...__rest], __rt) as types.Text; - } - format(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("format", [this, ...__rest], __rt) as types.Text; - } - fts5Insttoken(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("fts5_insttoken", [this, ...__rest], __rt) as types.Text; - } - fts5Locale | string>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Blob]]); - return runtime.funcCall("fts5_locale", [this, ...__rest], __rt) as types.Blob>>; - } - geopolyGroupBbox(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("geopoly_group_bbox", [this, ...__rest], __rt) as types.Blob; - } - glob | string>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("glob", [this, ...__rest], __rt) as types.Integer>>; - } - groupConcat(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("group_concat", [this, ...__rest], __rt) as types.Text; - } - hex(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("hex", [this, ...__rest], __rt) as types.Text; - } - ifnull | string>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("ifnull", [this, ...__rest], __rt) as types.Text>>; - } - instr | string>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("instr", [this, ...__rest], __rt) as types.Integer>>; - } - jsonArray(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_array", [this, ...__rest], __rt) as types.Text; - } - jsonbArray(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_array", [this, ...__rest], __rt) as types.Blob; - } - jsonbGroupArray(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("jsonb_group_array", [this, ...__rest], __rt) as types.Blob; - } - jsonbGroupObject | string>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Blob]]); - return runtime.funcCall("jsonb_group_object", [this, ...__rest], __rt) as types.Blob>>; - } - jsonbObject | string>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Blob]]); - return runtime.funcCall("jsonb_object", [this, ...__rest], __rt) as types.Blob>>; - } - jsonErrorPosition(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_error_position", [this, ...__rest], __rt) as types.Integer; - } - jsonGroupArray(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_group_array", [this, ...__rest], __rt) as types.Text; - } - jsonGroupObject | string>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("json_group_object", [this, ...__rest], __rt) as types.Text>>; - } - jsonObject | string>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("json_object", [this, ...__rest], __rt) as types.Text>>; - } - jsonQuote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("json_quote", [this, ...__rest], __rt) as types.Text; - } - jsonValid(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("json_valid", [this, ...__rest], __rt) as types.Integer; - } - lag | string>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("lag", [this, ...__rest], __rt) as types.Text>>; - } - lastValue(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("last_value", [this, ...__rest], __rt) as types.Text; - } - lead | string>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("lead", [this, ...__rest], __rt) as types.Text>>; - } - length(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("length", [this, ...__rest], __rt) as types.Integer; - } - like | string>(arg0: M0): types.Integer>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Integer]]); - return runtime.funcCall("like", [this, ...__rest], __rt) as types.Integer>>; - } - likely(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("likely", [this, ...__rest], __rt) as types.Text; - } - lower(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("lower", [this, ...__rest], __rt) as types.Text; - } - ltrim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("ltrim", [this, ...__rest], __rt) as types.Text; - } - max(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("max", [this, ...__rest], __rt) as types.Text; - } - min(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("min", [this, ...__rest], __rt) as types.Text; - } - octetLength(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("octet_length", [this, ...__rest], __rt) as types.Integer; - } - printf(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("printf", [this, ...__rest], __rt) as types.Text; - } - quote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("quote", [this, ...__rest], __rt) as types.Text; - } - randomblob(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("randomblob", [this, ...__rest], __rt) as types.Blob; - } - replace | string, M1 extends types.Text | string>(arg0: M0, arg1: M1): types.Text | runtime.NullOf>> { - const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("replace", [this, ...__rest], __rt) as types.Text | runtime.NullOf>>; - } - round(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("round", [this, ...__rest], __rt) as types.Real; - } - rtrim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("rtrim", [this, ...__rest], __rt) as types.Text; - } - soundex(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("soundex", [this, ...__rest], __rt) as types.Text; - } - sqliteCompileoptionGet(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("sqlite_compileoption_get", [this, ...__rest], __rt) as types.Text; - } - sqliteCompileoptionUsed(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("sqlite_compileoption_used", [this, ...__rest], __rt) as types.Integer; - } - strftime(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("strftime", [this, ...__rest], __rt) as types.Text; - } - stringAgg | string>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("string_agg", [this, ...__rest], __rt) as types.Text>>; - } - substr | string>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("substr", [this, ...__rest], __rt) as types.Text>>; - } - substring | string>(arg0: M0): types.Text>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); - return runtime.funcCall("substring", [this, ...__rest], __rt) as types.Text>>; - } - subtype(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("subtype", [this, ...__rest], __rt) as types.Integer; - } - sum(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("sum", [this, ...__rest], __rt) as types.Real; - } - total(): types.Real { - const [__rt, ...__rest] = runtime.match([], [[[], types.Real]]); - return runtime.funcCall("total", [this, ...__rest], __rt) as types.Real; - } - trim(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("trim", [this, ...__rest], __rt) as types.Text; - } - typeof(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("typeof", [this, ...__rest], __rt) as types.Text; - } - unhex | string>(arg0: M0): types.Blob>> { - const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Blob]]); - return runtime.funcCall("unhex", [this, ...__rest], __rt) as types.Blob>>; - } - unicode(): types.Integer { - const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); - return runtime.funcCall("unicode", [this, ...__rest], __rt) as types.Integer; - } - unistr(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("unistr", [this, ...__rest], __rt) as types.Text; - } - unistrQuote(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("unistr_quote", [this, ...__rest], __rt) as types.Text; - } - unlikely(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("unlikely", [this, ...__rest], __rt) as types.Text; - } - upper(): types.Text { - const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); - return runtime.funcCall("upper", [this, ...__rest], __rt) as types.Text; - } - zeroblob(): types.Blob { - const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); - return runtime.funcCall("zeroblob", [this, ...__rest], __rt) as types.Blob; - } + /** `concat_ws` — Concatenation with separator, skipping NULLs (3.44+). */ + @expose.unchecked() + concatWs | number | string | boolean | Uint8Array>(arg0: M0, ...rest: (types.Any | number | string | boolean | Uint8Array)[]): types.Text> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Any, allowPrimitive: true }, { type: types.Any, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("concat_ws", [this, ...__rest], __rt) as any; } + /** `format` — printf-style formatting (see printf.html). */ + @expose.unchecked() + format | number | string | boolean | Uint8Array>(arg0: M0, ...rest: (types.Any | number | string | boolean | Uint8Array)[]): types.Text> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Any, allowPrimitive: true }, { type: types.Any, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("format", [this, ...__rest], __rt) as any; } + /** `printf` — Alias of format(). */ + @expose.unchecked() + printf | number | string | boolean | Uint8Array>(arg0: M0, ...rest: (types.Any | number | string | boolean | Uint8Array)[]): types.Text> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Any, allowPrimitive: true }, { type: types.Any, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("printf", [this, ...__rest], __rt) as any; } + /** `glob` — X GLOB pattern — case-sensitive glob match (glob(P, X) function form). */ + @expose.unchecked() + glob | string>(arg0: M0): types.Bool>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Bool]]); return runtime.funcCall("glob", [this, ...__rest], __rt) as any; } + /** `instr` — 1-based position of the first occurrence of Y in X; 0 if absent. */ + @expose.unchecked() + instr | string>(arg0: M0): types.Integer>> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Integer]]); return runtime.funcCall("instr", [this, ...__rest], __rt) as any; } + /** `length` — Characters for TEXT, bytes for BLOB. */ + @expose.unchecked() + length(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("length", [this, ...__rest], __rt) as any; } + /** `like` — X LIKE pattern [ESCAPE e] — case-insensitive (ASCII) pattern match. */ + like | string>(arg0: M0): types.Bool>>; + /** `like` — X LIKE pattern [ESCAPE e] — case-insensitive (ASCII) pattern match. */ + like | string, M1 extends types.Text | string>(arg0: M0, arg1: M1): types.Bool | runtime.NullOf>>; + @expose.unchecked() + like(arg0: unknown, arg1?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }], types.Bool], [[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true }], types.Bool]]); return runtime.funcCall("like", [this, ...__rest], __rt) as any; } + /** `lower` — ASCII lowercase. */ + @expose.unchecked() + lower(): types.Text { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("lower", [this, ...__rest], __rt) as any; } + /** `ltrim` — Trim chars (default whitespace) from the left. */ + ltrim | string>(arg0?: M0): types.Text>>; + @expose.unchecked() + ltrim(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.funcCall("ltrim", [this, ...__rest], __rt) as any; } + /** `octet_length` — Length in bytes after TEXT encoding. */ + @expose.unchecked() + octetLength(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("octet_length", [this, ...__rest], __rt) as any; } + /** `replace` — Replace every occurrence of Y with Z in X. Empty pattern short-circuits NULL propagation from Z. */ + @expose.unchecked() + replace | string, M1 extends types.Text | string>(arg0: M0, arg1: M1): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.funcCall("replace", [this, ...__rest], __rt) as any; } + /** `soundex` — Soundex encoding; '?000' for unmappable input. */ + @expose.unchecked() + soundex(): types.Text<1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("soundex", [this, ...__rest], __rt) as any; } + /** `substr` — Substring from 1-based Y, length Z (to end if omitted). Empty-blob input yields NULL. */ + substr | number, M1 extends types.Integer | number>(arg0: M0, arg1?: M1): types.Text | runtime.NullOf>>; + @expose.unchecked() + substr(arg0: unknown, arg1?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Integer, allowPrimitive: true }], types.Text], [[{ type: types.Integer, allowPrimitive: true }, { type: types.Integer, allowPrimitive: true }], types.Text]]); return runtime.funcCall("substr", [this, ...__rest], __rt) as any; } + /** `substring` — Alias of substr(). Empty-blob input yields NULL. */ + substring | number, M1 extends types.Integer | number>(arg0: M0, arg1?: M1): types.Text | runtime.NullOf>>; + @expose.unchecked() + substring(arg0: unknown, arg1?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Integer, allowPrimitive: true }], types.Text], [[{ type: types.Integer, allowPrimitive: true }, { type: types.Integer, allowPrimitive: true }], types.Text]]); return runtime.funcCall("substring", [this, ...__rest], __rt) as any; } + /** `rtrim` — Trim chars (default whitespace) from the right. */ + rtrim | string>(arg0?: M0): types.Text>>; + @expose.unchecked() + rtrim(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.funcCall("rtrim", [this, ...__rest], __rt) as any; } + /** `trim` — Trim chars (default whitespace) from both ends. */ + trim | string>(arg0?: M0): types.Text>>; + @expose.unchecked() + trim(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.funcCall("trim", [this, ...__rest], __rt) as any; } + /** `unhex` — Hex string → BLOB; NULL on non-hex input. */ + unhex | string>(arg0?: M0): types.Blob<0 | 1>; + @expose.unchecked() + unhex(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Blob], [[{ type: types.Text, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("unhex", [this, ...__rest], __rt) as any; } + /** `unicode` — Code point of the first character. */ + @expose.unchecked() + unicode(): types.Integer<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("unicode", [this, ...__rest], __rt) as any; } + /** `unistr` — Decode \uXXXX escapes (3.50+). */ + @expose.unchecked() + unistr(): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("unistr", [this, ...__rest], __rt) as any; } + /** `upper` — ASCII uppercase. */ + @expose.unchecked() + upper(): types.Text { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("upper", [this, ...__rest], __rt) as any; } + /** `strftime` — Format a time value per the %-substitution string. */ + strftime | number | string | boolean | Uint8Array, M1 extends types.Text | string>(arg0: M0, arg1?: M1, ...rest: (types.Text | string)[]): types.Text<0 | 1>; + @expose.unchecked() + strftime(...args: unknown[]): any { const [__rt, ...__rest] = runtime.match(args, [[[{ type: types.Any, allowPrimitive: true }], types.Text], [[{ type: types.Any, allowPrimitive: true }, { type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("strftime", [this, ...__rest], __rt) as any; } + /** `json` — Validate + minify JSON (jsonb → binary). */ + @expose.unchecked() + json(): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Text]]); return runtime.funcCall("json", [this, ...__rest], __rt) as any; } + /** `jsonb` — Validate + minify JSON (jsonb → binary). */ + @expose.unchecked() + jsonb(): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([], [[[], types.Blob]]); return runtime.funcCall("jsonb", [this, ...__rest], __rt) as any; } + /** `json_array_length` — Array length at path (default '$'). */ + jsonArrayLength | string>(arg0?: M0): types.Integer<0 | 1>; + @expose.unchecked() + jsonArrayLength(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Integer], [[{ type: types.Text, allowPrimitive: true }], types.Integer]]); return runtime.funcCall("json_array_length", [this, ...__rest], __rt) as any; } + /** `json_error_position` — 0 if well-formed, else 1-based position of the first error. */ + @expose.unchecked() + jsonErrorPosition(): types.Integer { const [__rt, ...__rest] = runtime.match([], [[[], types.Integer]]); return runtime.funcCall("json_error_position", [this, ...__rest], __rt) as any; } + /** `json_extract` — Extract value(s) at path(s) — SQL value for scalars, JSON text otherwise. */ + @expose.unchecked() + jsonExtract | string>(arg0: M0, ...rest: (types.Text | string)[]): types.Any<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Any]]); return runtime.funcCall("json_extract", [this, ...__rest], __rt) as any; } + /** `jsonb_extract` — Extract at path(s) — JSONB for objects/arrays, SQL value for scalars. */ + @expose.unchecked() + jsonbExtract | string>(arg0: M0, ...rest: (types.Text | string)[]): types.Any<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Any]]); return runtime.funcCall("jsonb_extract", [this, ...__rest], __rt) as any; } + /** `json_insert` — Insert value at path if absent (more path/value pairs may follow). */ + @expose.unchecked() + jsonInsert | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_insert", [this, ...__rest], __rt) as any; } + /** `jsonb_insert` — Insert value at path if absent (more path/value pairs may follow). */ + @expose.unchecked() + jsonbInsert | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_insert", [this, ...__rest], __rt) as any; } + /** `json_array_insert` — Insert value into array at element path, shifting later elements (3.51+). */ + @expose.unchecked() + jsonArrayInsert | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_array_insert", [this, ...__rest], __rt) as any; } + /** `jsonb_array_insert` — Insert value into array at element path, shifting later elements (3.51+). */ + @expose.unchecked() + jsonbArrayInsert | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_array_insert", [this, ...__rest], __rt) as any; } + /** `json_object` — JSON object from alternating key/value args (label args must be TEXT). */ + @expose.unchecked() + jsonObject | number | string | boolean | Uint8Array>(arg0: M0): types.Text<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_object", [this, ...__rest], __rt) as any; } + /** `jsonb_object` — JSON object from alternating key/value args (label args must be TEXT). */ + @expose.unchecked() + jsonbObject | number | string | boolean | Uint8Array>(arg0: M0): types.Blob<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_object", [this, ...__rest], __rt) as any; } + /** `json_patch` — RFC-7396 MergePatch of Y into X. */ + @expose.unchecked() + jsonPatch | number | string | boolean | Uint8Array>(arg0: M0): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_patch", [this, ...__rest], __rt) as any; } + /** `jsonb_patch` — RFC-7396 MergePatch of Y into X. */ + @expose.unchecked() + jsonbPatch | number | string | boolean | Uint8Array>(arg0: M0): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_patch", [this, ...__rest], __rt) as any; } + /** `json_pretty` — Pretty-print JSON (3.46+). */ + jsonPretty | string>(arg0?: M0): types.Text<0 | 1>; + @expose.unchecked() + jsonPretty(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_pretty", [this, ...__rest], __rt) as any; } + /** `json_remove` — Remove the value(s) at path(s). */ + @expose.unchecked() + jsonRemove | string>(arg0: M0, ...rest: (types.Text | string)[]): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Text]]); return runtime.funcCall("json_remove", [this, ...__rest], __rt) as any; } + /** `jsonb_remove` — Remove the value(s) at path(s). */ + @expose.unchecked() + jsonbRemove | string>(arg0: M0, ...rest: (types.Text | string)[]): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, ...rest], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Text, allowPrimitive: true, rest: true }], types.Blob]]); return runtime.funcCall("jsonb_remove", [this, ...__rest], __rt) as any; } + /** `json_replace` — Replace value at path if present (more path/value pairs may follow). */ + @expose.unchecked() + jsonReplace | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_replace", [this, ...__rest], __rt) as any; } + /** `jsonb_replace` — Replace value at path if present (more path/value pairs may follow). */ + @expose.unchecked() + jsonbReplace | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_replace", [this, ...__rest], __rt) as any; } + /** `json_set` — Set value at path — insert or replace (more path/value pairs may follow). */ + @expose.unchecked() + jsonSet | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_set", [this, ...__rest], __rt) as any; } + /** `jsonb_set` — Set value at path — insert or replace (more path/value pairs may follow). */ + @expose.unchecked() + jsonbSet | string, M1 extends types.Any | number | string | boolean | Uint8Array>(arg0: M0, arg1: M1): types.Blob<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0, arg1], [[[{ type: types.Text, allowPrimitive: true }, { type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_set", [this, ...__rest], __rt) as any; } + /** `json_type` — 'object'|'array'|'integer'|... at path; NULL if path absent. */ + jsonType | string>(arg0?: M0): types.Text<0 | 1>; + @expose.unchecked() + jsonType(arg0?: unknown): any { const [__rt, ...__rest] = runtime.match([arg0], [[[], types.Text], [[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_type", [this, ...__rest], __rt) as any; } + /** `json_group_object` — Aggregate key/value pairs into a JSON object. */ + @expose.unchecked() + jsonGroupObject | number | string | boolean | Uint8Array>(arg0: M0): types.Text<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Text]]); return runtime.funcCall("json_group_object", [this, ...__rest], __rt) as any; } + /** `jsonb_group_object` — Aggregate key/value pairs into a JSONB object. */ + @expose.unchecked() + jsonbGroupObject | number | string | boolean | Uint8Array>(arg0: M0): types.Blob<1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Any, allowPrimitive: true }], types.Blob]]); return runtime.funcCall("jsonb_group_object", [this, ...__rest], __rt) as any; } + /** `json_each` — Table-valued: one row per element of the top-level array/object (or of the value at PATH). */ + @expose.unchecked() + jsonEach | string>(arg0?: M0): runtime.Srf<{ key: types.Any<1>; value: types.Any<1>; type: types.Text<1>; atom: types.Any<1>; id: types.Integer<1>; parent: types.Integer<1>; fullkey: types.Text<1>; path: types.Text<1> }, "json_each"> { return new runtime.Srf("json_each", [this, arg0].filter((a) => a !== undefined), [["key", types.Any], ["value", types.Any], ["type", types.Text], ["atom", types.Any], ["id", types.Integer], ["parent", types.Integer], ["fullkey", types.Text], ["path", types.Text]]) as any; } + /** `json_tree` — Table-valued: recursive walk of the whole JSON tree, one row per container and leaf. */ + @expose.unchecked() + jsonTree | string>(arg0?: M0): runtime.Srf<{ key: types.Any<1>; value: types.Any<1>; type: types.Text<1>; atom: types.Any<1>; id: types.Integer<1>; parent: types.Integer<1>; fullkey: types.Text<1>; path: types.Text<1> }, "json_tree"> { return new runtime.Srf("json_tree", [this, arg0].filter((a) => a !== undefined), [["key", types.Any], ["value", types.Any], ["type", types.Text], ["atom", types.Any], ["id", types.Integer], ["parent", types.Integer], ["fullkey", types.Text], ["path", types.Text]]) as any; } + /** `->` — JSON subcomponent at path, as JSON text; NULL if absent. */ + @expose.unchecked() + ['->'] | string>(arg0: M0): types.Text<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Text]]); return runtime.opCall(runtime.sql`->`, [this, ...__rest] as [unknown, unknown], __rt) as any; } + /** `->>` — JSON subcomponent at path, as SQL value; NULL if absent. */ + @expose.unchecked() + ['->>'] | string>(arg0: M0): types.Any<0 | 1> { const [__rt, ...__rest] = runtime.match([arg0], [[[{ type: types.Text, allowPrimitive: true }], types.Any]]); return runtime.opCall(runtime.sql`->>`, [this, ...__rest] as [unknown, unknown], __rt) as any; } } diff --git a/src/types/sqlite/index.ts b/src/types/sqlite/index.ts index 6bd2a269..44abbdfd 100644 --- a/src/types/sqlite/index.ts +++ b/src/types/sqlite/index.ts @@ -1,11 +1,11 @@ -// SQLite dialect barrel. Codegen (`./generate.ts`) will populate +// SQLite dialect barrel. Codegen (`./emit.ts`) will populate // generated/*.ts and augment this file between the [generated-*] // markers below. Hand-written entries live outside the markers. -export { SqliteValue } from "./base"; // [generated-start] -export { Blob } from "./generated/blob"; +export { Any } from "./overrides/any"; +export { Blob } from "./overrides/blob"; export { Bool } from "./overrides/bool"; export { Integer } from "./overrides/integer"; export { Real } from "./overrides/real"; -export { Text } from "./generated/text"; +export { Text } from "./overrides/text"; // [generated-end] diff --git a/src/types/sqlite/overrides/any.ts b/src/types/sqlite/overrides/any.ts new file mode 100644 index 00000000..ee880be1 --- /dev/null +++ b/src/types/sqlite/overrides/any.ts @@ -0,0 +1,75 @@ +// SQLite root class — hand-written core over the generated method +// surface (../generated/any.ts): dialect metadata plus the members +// whose signatures the codegen can't express. +// +// `dialect.root` / `dialect.bool` use barrel-import getters so the +// class-level dialect object can be initialized at class-def time +// without resolving the cyclic references at import time. Property +// access happens at method-call time. +import { Any as Generated } from "../generated/any"; +import { type Dialect } from "../../sql-value"; +import { meta } from "../../sql-value"; +import * as types from "../index"; +import { sql, type Sql } from "../../../builder/sql"; +import { expose } from "../../../exoeval/tool"; +import { isPlainData } from "../../../util"; + +export class Any extends Generated { + declare [meta]: { + __class: typeof Any; + __raw: Sql; + __nullability: N; + __aggregate: Any; + }; + static override dialect: Dialect = { + name: "sqlite", + get root() { return types.Any; }, + get bool() { return types.Bool; }, + }; + static override __typname = sql`any`; + static override __typnameText = "any"; + // Any-typed arguments accept every bindable primitive (the default + // typeof check would only accept strings). Used by runtime.match's + // allowPrimitive path. + static override acceptsPrimitive(v: unknown): boolean { + return ["number", "string", "boolean"].includes(typeof v) || v instanceof Uint8Array; + } + + isNull(): types.Bool<1> { + return types.Bool.from(sql`(${this.toSql()} IS NULL)`) as types.Bool<1>; + } + + isNotNull(): types.Bool<1> { + return types.Bool.from(sql`(${this.toSql()} IS NOT NULL)`) as types.Bool<1>; + } + + // Non-generic `.in()` — SQLite's shallow class hierarchy (SqlValue → + // Any → concrete) triggers TS2589 with the PG-style + // `, Vs>(this: T, ...)` signature, because + // each concrete class's `[meta].__any: Concrete` self-reference + // never bottoms out at that depth. PG dodges the recursion via a + // deeper 7-level chain. + // + // Trade-off: users don't get "same-typed args required" narrowing at + // compile time. Runtime enforcement via serialize() still applies. + // eslint-disable-next-line no-restricted-syntax -- generic vararg signature inexpressible in zod + @expose.unchecked() + in(...vals: [Any | boolean | number | string | Uint8Array, ...(Any | boolean | number | string | Uint8Array)[]]): types.Bool { + const wrapped = vals.map((v) => { + if (v instanceof Any) {return v;} + // Uint8Array is the blob primitive — a class instance, so it + // fails isPlainData but is accepted the same way the generated + // methods accept it (serialize() still enforces per-receiver). + if (!(v instanceof Uint8Array) && !isPlainData(v)) { + const name = (Object.getPrototypeOf(v) as { constructor?: { name?: string } } | null)?.constructor?.name ?? "anonymous"; + throw new TypeError( + `Any.in: cannot accept ${name} instance as a list value. ` + + `Pass a typegres expression or a primitive matching ${(this[meta].__class as typeof Any).__typnameText}.`, + ); + } + return this[meta].__class.serialize(v); + }); + const list = sql.join(wrapped.map((v) => v.toSql())); + return types.Bool.from(sql`(${this.toSql()} IN (${list}))`) as types.Bool; + } +} diff --git a/src/types/sqlite/overrides/blob.ts b/src/types/sqlite/overrides/blob.ts new file mode 100644 index 00000000..b90d89c7 --- /dev/null +++ b/src/types/sqlite/overrides/blob.ts @@ -0,0 +1,14 @@ +// BLOB storage-class view — hand-written behavior over the generated +// method surface (../generated/blob.ts). Uint8Array instances are the +// accepted primitive (instanceof, not typeof), and blobs come back as +// Uint8Array too: the driver normalizes result blobs to \x-prefixed +// hex (PG bytea repr — see driver.ts normalizeValue), which +// deserialize() parses back to bytes. +import { Blob as Generated } from "../generated/blob"; + +export class Blob extends Generated { + static override acceptsPrimitive(v: unknown): boolean { return v instanceof Uint8Array; } + override deserialize(raw: string): Uint8Array { + return Uint8Array.from(Buffer.from(raw.startsWith("\\x") ? raw.slice(2) : raw, "hex")); + } +} diff --git a/src/types/sqlite/overrides/bool.ts b/src/types/sqlite/overrides/bool.ts index 9379d272..98dd5617 100644 --- a/src/types/sqlite/overrides/bool.ts +++ b/src/types/sqlite/overrides/bool.ts @@ -1,28 +1,17 @@ -// SQLite has no native bool type — the storage class is INTEGER 0/1. -// `__typname = INTEGER` for CAST(...); `__typnameText = "bool"` is the -// key used for error messages. Codegen doesn't emit a bool.ts under -// `generated/` (bool isn't a SQLite storage class), so this override -// stands on its own — extends SqliteValue directly rather than a -// generated base. -import { SqliteValue } from "../base"; +// The boolean view's hand-written behavior over the generated surface +// (../generated/bool.ts — chrome + iif and friends). SQLite has no +// native bool — the storage class is INTEGER 0/1 (the generated CAST +// target is INTEGER), so deserialization reads "1"/"0" and the +// and/or/not connectives build on integer truthiness. +import { Bool as Generated } from "../generated/bool"; import { boolAnd, boolOr, boolNot } from "../../bool"; -import { sql, type Sql } from "../../../builder/sql"; -import { meta } from "../../sql-value"; import type { StrictNull, NullOf } from "../../runtime"; -export class Bool extends SqliteValue { - declare [meta]: { - __class: typeof Bool; - __raw: Sql; - __nullability: N; - __nullable: Bool<0 | 1>; - __nonNullable: Bool<1>; - __aggregate: Bool; - __any: Bool; - }; - static override __typname = sql`INTEGER`; - static override __typnameText = "bool"; +export class Bool extends Generated { static override primitiveTs = "boolean"; + // Restore the typeof narrowing (Any's permissive acceptsPrimitive + // override is inherited by statics). + static override acceptsPrimitive(v: unknown): boolean { return typeof v === "boolean"; } override deserialize(raw: string): boolean { return raw === "1"; } and>(other: M): Bool>> { @@ -36,4 +25,4 @@ export class Bool extends SqliteValue { not(): Bool { return Bool.from(boolNot(this.toSql(), Bool.dialect.name)) as any; } -} \ No newline at end of file +} diff --git a/src/types/sqlite/overrides/integer.ts b/src/types/sqlite/overrides/integer.ts index 72ac66cb..b2de1d5e 100644 --- a/src/types/sqlite/overrides/integer.ts +++ b/src/types/sqlite/overrides/integer.ts @@ -1,9 +1,17 @@ +// INTEGER storage-class view — hand-written behavior over the +// generated method surface (../generated/integer.ts): deserialization +// and the integral-number narrowing for primitive args. import { Integer as Generated } from "../generated/integer"; -// better-sqlite3 hands us JS numbers directly; the SqliteDriver stringifies -// them via `String(v)` before hydration (so PG and SQLite share one -// deserialize path). parseInt reverses that stringification. -export class Integer extends Generated { +export class Integer extends Generated { + // Codegen reads the type table's matching primitiveTs to build + // `M0 extends Integer | number` arg constraints. static override primitiveTs = "number"; + // Typed-position rule: an integer-claimed argument accepts a JS + // number only when it IS an integer — fractional values never + // silently truncate through CAST(? AS INTEGER); they either route + // to a real overload or fail dispatch. Explicit truncation remains + // available via Integer.from(x) / .cast(Integer). + static override acceptsPrimitive(v: unknown): boolean { return typeof v === "number" && Number.isInteger(v); } override deserialize(raw: string): number { return parseInt(raw, 10); } } diff --git a/src/types/sqlite/overrides/real.ts b/src/types/sqlite/overrides/real.ts index f6cc096c..488e09c0 100644 --- a/src/types/sqlite/overrides/real.ts +++ b/src/types/sqlite/overrides/real.ts @@ -1,6 +1,12 @@ +// REAL storage-class view — hand-written behavior over the generated +// method surface (../generated/real.ts): deserialization and the +// typeof narrowing for primitive args. import { Real as Generated } from "../generated/real"; -export class Real extends Generated { +export class Real extends Generated { static override primitiveTs = "number"; + // Restore typeof narrowing (Any's permissive acceptsPrimitive is + // inherited by statics). + static override acceptsPrimitive(v: unknown): boolean { return typeof v === "number"; } override deserialize(raw: string): number { return parseFloat(raw); } } diff --git a/src/types/sqlite/overrides/text.ts b/src/types/sqlite/overrides/text.ts new file mode 100644 index 00000000..4b059435 --- /dev/null +++ b/src/types/sqlite/overrides/text.ts @@ -0,0 +1,13 @@ +// TEXT storage-class view — hand-written behavior over the generated +// method surface (../generated/text.ts): the typeof narrowing for +// primitive args. Deserialization is the inherited identity — the +// declare only narrows the return type. +import { Text as Generated } from "../generated/text"; + +export class Text extends Generated { + static override primitiveTs = "string"; + // Restore typeof narrowing (Any's permissive acceptsPrimitive is + // inherited by statics). + static override acceptsPrimitive(v: unknown): boolean { return typeof v === "string"; } + declare deserialize: (raw: string) => string; +} diff --git a/src/types/sqlite/signatures.verify.test.ts b/src/types/sqlite/signatures.verify.test.ts new file mode 100644 index 00000000..76edea5e --- /dev/null +++ b/src/types/sqlite/signatures.verify.test.ts @@ -0,0 +1,432 @@ +// Property verifier for the sqlite facts (docs/*.json, loaded by +// emit.ts as SIGNATURES) — fast-check generated inputs (seeded per +// function, so CI is reproducible; failures shrink to minimal args) +// against the real SQLite engine (better-sqlite3, the same build the +// driver uses). +// +// Per overload: +// 1. Valid non-null inputs never throw, and typeof(result) matches +// the claimed return type ("never"/"propagates" ⇒ exactly the +// claim; "always"/"on_error" ⇒ the claim or NULL). +// 2. nul: "propagates" ⇒ NULL in any single arg position → NULL out. +// 3. nul: "never" ⇒ non-NULL result even with NULL inputs. +// 4. EQUIVALENCE: the emitted typed surface (runtime.match dispatch, +// primitive serialization, CAST choices, arg order) computes the +// exact same value and storage class as handwritten SQL. This is +// the value-level oracle — it tests the layer typegres wrote, with +// the engine as ground truth. +// Plus the completeness gate: every pragma_function_list name is +// either defined in SIGNATURES or listed in EXCLUSIONS — and every +// non-operator definition exists in pragma_function_list (typo guard). + +import { describe, test, expect, beforeAll, afterAll } from "vitest"; +import Database from "better-sqlite3"; +import * as fs from "node:fs"; +import * as path from "node:path"; +import fc from "fast-check"; +import camelcase from "camelcase"; +import { SIGNATURES, EXCLUSIONS } from "./emit.ts"; +import type { EmitFn as FnDef, EmitOverload as Overload, EmitArg as ArgDef } from "../emission/facts.ts"; +import { UNARY_OPERATOR_ALIASES } from "../emission/common.ts"; +import { Database as TypegresDatabase } from "../../database"; +import { compile, sql } from "../../builder/sql"; +import * as types from "./index"; + +let db: Database.Database; +beforeAll(() => { db = new Database(":memory:"); }); +afterAll(() => { db.close(); }); + +// Statement texts repeat per (fn, shape) across fast-check runs — +// cache the prepared handles. +const stmtCache = new Map(); +const prep = (text: string): Database.Statement => { + let s = stmtCache.get(text); + if (!s) { s = db.prepare(text); stmtCache.set(text, s); } + return s; +}; + +// Compile context for the typed-surface side (no driver needed — the +// compiled text/values run on the raw better-sqlite3 handle above). +const tg = new TypegresDatabase({ dialect: "sqlite" }); + +// Stable per-function seed so CI runs are reproducible; on failure +// fast-check prints the seed + shrunk counterexample. +const seedFor = (s: string): number => [...s].reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 7); +const RUNS = 12; + +// --- arbitraries ------------------------------------------------------------ +// Canonical values are the TYPED-side primitives (what a user passes +// to a method: number/string/boolean/Uint8Array). toRaw() derives the +// engine-native bind for the handwritten-SQL side: integer-claimed +// numbers bind as BigInt (sqlite3_bind_int64 — better-sqlite3 binds +// every JS number as REAL), booleans as 0n/1n (not bindable at all). + +const ARB_TYPE: { [k in string]: fc.Arbitrary } = { + integer: fc.integer({ min: -(2 ** 31), max: 2 ** 31 }), + real: fc.double({ noNaN: true, noDefaultInfinity: true, min: -1e12, max: 1e12 }), + text: fc.oneof(fc.string({ maxLength: 12 }), fc.constantFrom("", "quo'te", "αβγ", "Hello World")), + blob: fc.uint8Array({ maxLength: 8 }), + bool: fc.boolean(), + // `any` args reach SQL as bare params (no CAST), where JS numbers + // land as REAL — so integral numbers are equivalent on both sides. + any: fc.oneof( + fc.integer({ min: -1000, max: 1000 }), + fc.double({ noNaN: true, noDefaultInfinity: true, min: -1e6, max: 1e6 }), + fc.string({ maxLength: 8 }), + fc.boolean(), + fc.uint8Array({ maxLength: 6 }), + ), +}; + +const jsonScalar = fc.oneof( + fc.integer({ min: -100, max: 100 }), + fc.double({ noNaN: true, noDefaultInfinity: true, min: -1e6, max: 1e6 }), + fc.string({ maxLength: 6 }), + fc.boolean(), + fc.constant(null), +); +const ARB_HINT: { [k in string]: fc.Arbitrary } = { + json: fc.oneof( + fc.dictionary(fc.string({ minLength: 1, maxLength: 4 }), jsonScalar, { maxKeys: 4 }).map((o) => JSON.stringify(o)), + fc.array(jsonScalar, { maxLength: 5 }).map((a) => JSON.stringify(a)), + fc.constantFrom('{}', '[]', '{"a":{"b":"c"},"d":[true,null]}'), + ), + jsonpath: fc.constantFrom("$", "$.a", "$[0]", "$.a.b", "$[1]"), + "json-array": fc.array(jsonScalar, { maxLength: 5 }).map((a) => JSON.stringify(a)), + "jsonpath-element": fc.constantFrom("$[0]", "$[1]", "$[2]"), + // JSON can't hold BLOB values — value-position args draw from this. + plain: fc.oneof( + fc.integer({ min: -1000, max: 1000 }), + fc.double({ noNaN: true, noDefaultInfinity: true, min: -1e6, max: 1e6 }), + fc.string({ maxLength: 8 }), + ), + // No 'now': it is statement-time-dependent, and the equivalence + // property runs the raw and typed statements at different instants. + datetime: fc + .date({ min: new Date("1970-01-02"), max: new Date("2099-12-30") }) + .chain((d) => fc.constantFrom(d.toISOString().slice(0, 10), d.toISOString().slice(0, 19).replace("T", " "))), + "datetime-modifier": fc.constantFrom("+1 day", "-2 hours", "start of month", "weekday 0", "+3 minutes"), + "strftime-format": fc.constantFrom("%Y", "%Y-%m-%d", "%H:%M", "%s", "%j", "%d/%m"), + "printf-format": fc.constantFrom("%s", "x=%s!", "[%s]", "%d", "%.2f"), + "like-pattern": fc.constantFrom("%", "a%", "_b%", "%o%", "abc"), + "escape-char": fc.constantFrom("\\", "!", "#"), + percent: fc.double({ noNaN: true, noDefaultInfinity: true, min: 0, max: 100 }), + fraction: fc.double({ noNaN: true, noDefaultInfinity: true, min: 0, max: 1 }), + "unit-interval": fc.double({ noNaN: true, noDefaultInfinity: true, min: 0, max: 1 }), + // Allocation sizes — unbounded integers would allocate GB blobs + // (zeroblob) or exceed SQLITE_MAX_LENGTH. + "byte-count": fc.integer({ min: 0, max: 1024 }), +}; + +const arbFor = (a: ArgDef): fc.Arbitrary => + a.hint ? ARB_HINT[a.hint]! : ARB_TYPE[a.type!]!; + +// Engine-native bind for the handwritten-SQL side. +const toRaw = (a: ArgDef, v: unknown): unknown => + typeof v === "boolean" ? (v ? 1n : 0n) + : a.type === "integer" && typeof v === "number" ? BigInt(v) + : v; + +// BigInt/blob-safe arg rendering for assertion messages. +const fmt = (args: unknown[]): string => + `(${args.map((v) => (typeof v === "bigint" ? `${v}n` : v instanceof Uint8Array ? `blob[${v.length}]` : JSON.stringify(v))).join(", ")})`; + +// --- probe construction ---------------------------------------------------- + +const probe = (fn: FnDef, args: unknown[], extraRow?: unknown): string => { + const qs = args.map(() => "?"); + let sqlText: string; + if (fn.kind === "binop") { + sqlText = `SELECT typeof((? ${fn.sql} ?)) AS t`; + } else if (fn.kind === "unaryop") { + sqlText = `SELECT typeof((${fn.sql} ?)) AS t`; + } else if (fn.kind === "aggregate") { + // arg0 comes from rows; remaining args are per-call. + sqlText = `WITH d(v) AS (SELECT ? UNION ALL SELECT ?) SELECT typeof(${fn.sql}(v${qs.slice(1).map((q) => `, ${q}`).join("")})) AS t FROM d`; + args = [args[0], extraRow ?? args[0], ...args.slice(1)]; + } else { + sqlText = `SELECT typeof(${fn.sql}(${qs.join(", ")})) AS t`; + } + const row = prep(sqlText).get(...args) as { t: string }; + return row.t; +}; + +// Expected storage class for a claimed return type given the args used. +const expectedTypeof = (o: Overload, args: ArgDef[]): string | null => { + if (o.returns === "arg0") { return args[0]!.type === "bool" ? "integer" : args[0]!.type === "any" ? null : args[0]!.type; } + if (o.returns === "bool") { return "integer"; } + if (o.returns === "any") { return null; } // any non-null storage class is fine + return o.returns; +}; + +// Arg shapes per overload: optional args exercised both present and +// absent; variadic exercised at +1 repeat. +const shapesOf = (o: Overload): ArgDef[][] => { + const req = o.args.filter((a) => !a.optional); + const shapes: ArgDef[][] = [o.args]; + if (req.length !== o.args.length) { shapes.push(req); } + if (o.variadic) { shapes.push([...o.args, o.args[o.args.length - 1]!]); } + return shapes; +}; + +describe("completeness gate", () => { + test("every pragma_function_list entry is defined or excluded; every non-operator definition exists", () => { + const pragmaNames = new Set( + (db.prepare("SELECT DISTINCT name FROM pragma_function_list").all() as { name: string }[]).map((r) => r.name), + ); + const defined = new Set(SIGNATURES.map((f) => f.sql)); + const excluded = new Set(EXCLUSIONS); + + const unaccounted = [...pragmaNames].filter((n) => !defined.has(n) && !excluded.has(n)); + expect(unaccounted, `pragma functions neither defined nor excluded`).toEqual([]); + + // Operators aren't listed in pragma_function_list (except -> and + // ->>, which appear as both) — the typo guard applies to + // functions only. Table-valued functions are eponymous virtual + // tables, not pragma_function_list entries — their typo guard is + // that they prepare in FROM position. + const phantom = SIGNATURES.filter((f) => !f.isSrf && (f.kind === "scalar" || f.kind === "aggregate") && !pragmaNames.has(f.sql)).map((f) => f.sql); + expect(phantom, `defined but not in pragma_function_list (typo?)`).toEqual([]); + const srfPhantom = SIGNATURES.filter((f) => f.isSrf).filter((f) => { + try { db.prepare(`SELECT * FROM ${f.sql}('{}')`); return false; } catch { return true; } + }).map((f) => f.sql); + expect(srfPhantom, `SRF defined but not a table-valued function (typo?)`).toEqual([]); + + const doubleBooked = SIGNATURES.filter((f) => excluded.has(f.sql)).map((f) => f.sql); + expect(doubleBooked, `both defined and excluded`).toEqual([]); + }); +}); + +describe("determinism facts", () => { + test("scalar `deterministic` matches the engine's SQLITE_DETERMINISTIC flag", () => { + // The flag (0x800) is only meaningful on scalar registrations — + // aggregates never carry it (it's a scalar-expression concept for + // indexes/generated columns), so the schema convention is + // aggregates ⇒ deterministic: true (same input set ⇒ same result). + const rows = db.prepare("SELECT name, flags FROM pragma_function_list WHERE type = 's'").all() as { name: string; flags: number }[]; + const engine = new Map(); + for (const r of rows) { engine.set(r.name, engine.get(r.name) || !!(r.flags & 0x800)); } + for (const f of SIGNATURES) { + if (f.isSrf) { + // Virtual tables carry no SQLITE_DETERMINISTIC flag; the + // schema convention is isSrf ⇒ deterministic: true. + expect(f.deterministic, `${f.sql} (SRF) must claim deterministic: true`).toBe(true); + } else if (f.kind === "scalar") { + expect(f.deterministic, `${f.sql} deterministic fact vs engine flag`).toBe(engine.get(f.sql)); + } else if (f.kind === "aggregate") { + expect(f.deterministic, `${f.sql} (aggregate) must claim deterministic: true`).toBe(true); + } + } + }); + + test("non-deterministic functions are not emitted to the typed surface", () => { + // Mirrors PG's provolatile='i' filter: random/changes/... exist as + // facts but never as generated methods — reach them via raw + // sql`random()`. + const generatedDir = path.join(import.meta.dirname, "generated"); + const generated = fs.readdirSync(generatedDir) + .filter((f) => f.endsWith(".ts")) + .map((f) => fs.readFileSync(path.join(generatedDir, f), "utf8")) + .join("\n"); + const nondet = SIGNATURES.filter((f) => f.deterministic === false); + expect(nondet.length, "expected some non-deterministic facts").toBeGreaterThan(0); + for (const f of nondet) { + expect(generated.includes(`funcCall(${JSON.stringify(f.sql)}`), `${f.sql} must not be emitted`).toBe(false); + } + }); +}); + +// Table-valued claims: exact projected column list (names, in order) +// and per-row storage class for concretely-claimed columns, across +// generated args in FROM position. +const verifySrf = (fn: FnDef): void => { + const cols = fn.outColumns!; + const stmt = db.prepare(`SELECT * FROM ${fn.sql}('{"a":1}')`); + expect(stmt.columns().map((c) => c.name), `${fn.sql} projected columns`).toEqual(cols.map((c) => c.name)); + for (const [oi, o] of fn.overloads.entries()) { + for (const shape of shapesOf(o)) { + fc.assert( + fc.property(fc.tuple(...shape.map(arbFor)), (canon) => { + const args = canon.map((v, i) => toRaw(shape[i]!, v)); + const sel = cols.map((c) => `typeof("${c.name}") AS "${c.name}"`).join(", "); + let rows: { [column: string]: string }[]; + try { + rows = db.prepare(`SELECT ${sel} FROM ${fn.sql}(${shape.map(() => "?").join(", ")})`).all(...args) as { [column: string]: string }[]; + } catch (e) { + throw new Error(`${fn.sql} threw on claimed-valid args ${fmt(args)}: ${(e as Error).message}`, { cause: e }); + } + for (const row of rows) { + for (const c of cols) { + if (c.type === "any") { continue; } + expect([c.type, "null"], `${fn.sql}${fmt(args)} column ${c.name} storage class`).toContain(row[c.name]); + } + } + }), + { seed: seedFor(fn.sql) + oi, numRuns: RUNS }, + ); + } + } +}; + +describe("signature claims vs engine behavior", () => { + for (const fn of SIGNATURES) { + test(`${fn.kind} ${fn.sql}`, () => { + if (fn.isSrf) { + verifySrf(fn); + return; + } + for (const [oi, o] of fn.overloads.entries()) { + for (const [si, shape] of shapesOf(o).entries()) { + // Aggregates draw arg0 from rows — generate one extra row value. + const arbs = [...shape.map(arbFor), ...(fn.kind === "aggregate" ? [arbFor(shape[0]!)] : [])]; + fc.assert( + fc.property(fc.tuple(...arbs), (canon) => { + const extraRow = fn.kind === "aggregate" ? toRaw(shape[0]!, canon[shape.length]) : undefined; + const args = canon.slice(0, shape.length).map((v, i) => toRaw(shape[i]!, v)); + // (1) no-throw + return storage class + let t: string; + try { + t = probe(fn, args, extraRow); + } catch (e) { + throw new Error(`${fn.sql} threw on claimed-valid args ${fmt(args)}: ${(e as Error).message}`, { cause: e }); + } + const want = expectedTypeof(o, shape); + if (o.nullability === "never" || o.nullability === "propagates") { + if (want !== null) { + expect(t, `${fn.sql}${fmt(args)} storage class`).toBe(want); + } else { + expect(t, `${fn.sql}${fmt(args)} must be non-null`).not.toBe("null"); + } + } else { + if (want !== null) { + expect([want, "null"], `${fn.sql}${fmt(args)} storage class`).toContain(t); + } + } + // (2) NULL propagation / (3) never-null — scalar/op only + // (aggregates skip NULL rows by definition). + if (fn.kind !== "aggregate") { + for (let i = 0; i < shape.length; i++) { + if (o.nullPositions && !o.nullPositions.includes(i)) { continue; } + const withNull = args.map((v, j) => (j === i ? null : v)); + const tn = probe(fn, withNull); + if (o.nullability === "propagates") { + expect(tn, `${fn.sql} with NULL at arg ${i} must propagate NULL`).toBe("null"); + } else if (o.nullability === "never") { + expect(tn, `${fn.sql} with NULL at arg ${i} must stay non-NULL`).not.toBe("null"); + } + } + } + }), + { seed: seedFor(fn.sql) + oi * 31 + si, numRuns: RUNS }, + ); + } + } + }); + } +}); + +// --- typed surface ≡ engine --------------------------------------------------- +// The value-level oracle. For generated args, evaluate the SAME call +// two ways and demand identical (value, storage class): +// raw: handwritten `SELECT fn(?, ...)` with engine-native binds +// typed: the emitted method surface — runtime.match dispatch → +// serialization/CASTs → compiled SQL +// A divergence means the layer typegres wrote (dispatch, casts, arg +// order, serialization) changed the meaning of the call — exactly the +// class of bug the facts can't catch (e.g. a primitive routed through +// a truncating CAST). +// +// Two modes: +// instance: non-receiver args wrapped as typed instances +// (Integer.from(7)...) — pins THIS overload exactly, so +// every overload (including mixed integer/real arithmetic) +// is checked against its own raw form. +// primitive: non-receiver args as bare JS primitives — the common +// path users take. A primitive can only ever select ONE +// overload per receiver class (match routes it to the +// owner / lossless winner), so this mode runs only when +// dispatch is unambiguous: the fn has a single overload +// hosted on this receiver. + +const HOST_CLASS: { [k in string]: { from: (v: unknown) => unknown } } = { + integer: types.Integer, real: types.Real, text: types.Text, + blob: types.Blob, bool: types.Bool, any: types.Any, +}; +// Hand-written base members with bespoke signatures — not the generated surface. +const NOT_GENERATED = new Set(["coalesce", "in"]); + +const methodName = (fn: FnDef): string => + fn.kind === "scalar" || fn.kind === "aggregate" ? camelcase(fn.sql) + : fn.kind === "unaryop" ? (UNARY_OPERATOR_ALIASES[fn.sql] ?? fn.sql) + : fn.sql; + +const rawCallSql = (fn: FnDef, n: number): string => { + if (fn.kind === "binop") { return `(? ${fn.sql} ?)`; } + if (fn.kind === "unaryop") { return `(${fn.sql} ?)`; } + return `${fn.sql}(${Array.from({ length: n }, () => "?").join(", ")})`; +}; + +const sameValue = (a: unknown, b: unknown): boolean => { + if (a instanceof Uint8Array && b instanceof Uint8Array) { + return a.length === b.length && a.every((x, i) => x === b[i]); + } + return Object.is(a, b); +}; + +// Does a canonical value fit a claimed storage class's primitive domain? +const fitsClaim = (t: string, v: unknown): boolean => + t === "integer" ? typeof v === "number" && Number.isInteger(v) + : t === "real" ? typeof v === "number" + : t === "text" ? typeof v === "string" + : t === "blob" ? v instanceof Uint8Array + : t === "bool" ? typeof v === "boolean" + : true; // any + +// Wrap a canonical value as the typed instance pinning the claimed +// overload. Hint-driven values that don't fit the claim (JSON text +// generated for a JSONB-blob arg — we can't synthesize real JSONB) +// wrap as their natural class instead, exercising the text overload. +const wrap = (a: ArgDef, v: unknown): unknown => { + const cls = (fitsClaim(a.type!, v) + ? HOST_CLASS[a.type!]! + : typeof v === "string" ? types.Text + : typeof v === "number" ? types.Real + : types.Any) as { from: (v: unknown) => unknown }; + return cls.from(v); +}; + +describe("typed surface ≡ engine", () => { + for (const fn of SIGNATURES) { + if (fn.isSrf || fn.deterministic === false || NOT_GENERATED.has(fn.sql)) { continue; } + test(`${fn.kind} ${fn.sql}`, () => { + for (const [oi, o] of fn.overloads.entries()) { + const hostedCount = fn.overloads.filter((x) => x.args[0]?.type === o.args[0]?.type).length; + for (const [si, shape] of shapesOf(o).entries()) { + // Zero-arg shapes have no receiver — like pg, they're not on + // the method surface (pi(), unixepoch()); reach them via raw sql. + if (shape.length === 0) { continue; } + const modes: ("instance" | "primitive")[] = hostedCount === 1 ? ["instance", "primitive"] : ["instance"]; + for (const [mi, mode] of modes.entries()) { + fc.assert( + fc.property(fc.tuple(...shape.map(arbFor)), (canon) => { + // raw: engine-native binds, handwritten call + const rawArgs = canon.map((v, i) => toRaw(shape[i]!, v)); + const rawSql = rawCallSql(fn, shape.length); + const raw = prep(`SELECT typeof(${rawSql}) AS t, ${rawSql} AS v`).get(...rawArgs, ...rawArgs) as { t: string; v: unknown }; + // typed: the method surface + const receiver = wrap(shape[0]!, canon[0]) as { [m: string]: (...a: unknown[]) => { toSql: () => unknown } }; + const rest = canon.slice(1).map((v, i) => (mode === "instance" ? wrap(shape[i + 1]!, v) : v)); + const expr = receiver[methodName(fn)]!(...rest).toSql(); + const compiled = compile(sql`SELECT typeof(${expr}) AS t, ${expr} AS v`, { database: tg }); + const typed = prep(compiled.text).get(...(compiled.values as unknown[])) as { t: string; v: unknown }; + expect(typed.t, `${fn.sql}${fmt(canon)} [${mode}] typed storage class vs raw`).toBe(raw.t); + expect(sameValue(typed.v, raw.v), `${fn.sql}${fmt(canon)} [${mode}] typed value ${String(typed.v)} vs raw ${String(raw.v)}`).toBe(true); + }), + { seed: seedFor(fn.sql) ^ (oi * 61 + si * 7 + mi), numRuns: RUNS }, + ); + } + } + } + }); + } +}); diff --git a/src/types/sqlite/smoke.test.ts b/src/types/sqlite/smoke.test.ts index b992f4fb..77089693 100644 --- a/src/types/sqlite/smoke.test.ts +++ b/src/types/sqlite/smoke.test.ts @@ -13,7 +13,7 @@ import { SqliteDriver } from "../../driver"; import type { Connection } from "../../database"; import { Database } from "../../database"; import { compile, sql } from "../../builder/sql"; -import { Integer, Text } from "./index"; +import { Integer, Real, Text, Blob, Bool } from "./index"; let driver: SqliteDriver; let db: Database; @@ -88,18 +88,164 @@ test(".in() rejects when no literal matches", async () => { expect(r.rows[0]!["v"]).toBe("0"); }); -test("codegen'd Integer method accepts a JS-native primitive arg", async () => { - // atan2 takes a second Integer arg — the emit shape allows a - // number primitive alongside the typed Integer via runtime.match. +test("emitted Integer method accepts a JS-native primitive arg", async () => { + // atan2 takes a second numeric arg — the emitted signature allows a + // number primitive alongside the typed Integer. const expr = Integer.from(1).atan2(1); const r = await conn.execute(sql`SELECT ${expr.toSql()} as v`); expect(parseFloat(r.rows[0]!["v"]!)).toBeCloseTo(Math.PI / 4, 5); }); -test("codegen'd method rejects the wrong JS primitive type at runtime", async () => { - // atan2 doesn't accept a string primitive — runtime.match throws. - expect(() => Integer.from(1).atan2("nope" as unknown as number)) - .toThrow(/No matching overload/); +test("same-return integer/real twins route primitives to Real (no truncation)", async () => { + // atan2's Integer and Real overloads both return Real, so a number + // primitive must serialize via the value-preserving Real case — + // CAST(? AS REAL), not CAST(? AS INTEGER) (which truncated 0.5 → 0 + // and returned π/2). Where returns DIFFER (minus/plus/...), + // fractional numbers fail dispatch instead (see the + // integral-vs-fractional test below). + const expr = Integer.from(1).atan2(0.5); + const compiled = compile(expr.toSql(), { database: db }); + // Receiver literal casts INTEGER (Integer.from(1)); the primitive + // ARG casts REAL. + expect(compiled.text).toContain("CAST(? AS REAL)"); + const r = await conn.execute(sql`SELECT ${expr.toSql()} as v`); + expect(parseFloat(r.rows[0]!["v"]!)).toBeCloseTo(Math.atan2(1, 0.5), 5); +}); + +test("integer positions never silently truncate fractional numbers", async () => { + // Integral numbers take the integer overload — INTEGER semantics. + const intDiv = Integer.from(7).divide(2); + expect((await conn.execute(sql`SELECT ${intDiv.toSql()} as v`)).rows[0]!["v"]).toBe("3"); + // Fractional numbers don't fit any primitive-accepting overload on + // an Integer receiver — rejected at dispatch, not truncated to 0. + expect(() => (Integer.from(7) as any).divide(0.5)).toThrow(/No matching overload/); + // Explicit truncation stays available as a cast. + const trunc = Integer.from(2.9); + expect((await conn.execute(sql`SELECT ${trunc.toSql()} as v`)).rows[0]!["v"]).toBe("2"); +}); + +test("Blob roundtrip: driver normalizes to \\x-hex; deserialize parses back", async () => { + const r = await conn.execute(sql`SELECT ${Blob.from(new Uint8Array([1, 255])).toSql()} as v`); + expect(r.rows[0]!["v"]).toBe("\\x01ff"); + expect(Blob.from(new Uint8Array()).deserialize(r.rows[0]!["v"]!)).toEqual(new Uint8Array([1, 255])); +}); + +test(".in() accepts Uint8Array (the blob primitive)", async () => { + const hit = Blob.from(new Uint8Array([1, 2])).in(new Uint8Array([1, 2]), new Uint8Array([3])); + expect((await conn.execute(sql`SELECT ${hit.toSql()} as v`)).rows[0]!["v"]).toBe("1"); +}); + +test("json_each: table-valued function via db.from", async () => { + const each = Text.from('{"a":1,"b":2}').jsonEach(); + const rows = await conn.execute(db.from(each).orderBy(({ json_each }) => json_each.key)); + expect(rows).toMatchObject([ + { key: "a", value: "1", type: "integer" }, + { key: "b", value: "2", type: "integer" }, + ]); +}); + +test("optional-arity dispatch: omitted and supplied optional args both match", async () => { + // Regression: match had no arity gate, so a zero-matcher case + // ([[ ]], e.g. round()'s no-arg overload) vacuously matched ANY + // call and serialization crashed indexing past the matcher list. + const r0 = await conn.execute(sql`SELECT ${Real.from(2.567).round().toSql()} as v`); + expect(parseFloat(r0.rows[0]!["v"]!)).toBe(3); + const r2 = await conn.execute(sql`SELECT ${Real.from(2.567).round(2).toSql()} as v`); + expect(parseFloat(r2.rows[0]!["v"]!)).toBeCloseTo(2.57, 5); + // Wrong-typed args reject cleanly, not with a crash. + expect(() => (Text.from("now") as any).date(123)).toThrow(/No matching overload/); + // Extra args on a single-overload one-liner follow JS convention: + // dropped (the impl binds declared params only), never reaching SQL. + const s = await conn.execute(sql`SELECT ${(Integer.from(-5) as any).sign(1, 2).toSql()} as v`); + expect(s.rows[0]!["v"]).toBe("-1"); +}); + +test("wrong primitive type: TS refuses AND runtime.match throws", () => { + // Strict runtime model: match validates every call (RPC or direct), + // so casting past TS doesn't fall through to SQLite coercion — it + // throws at the gate. SQLite's dynamism is reachable only via + // explicit cast(). + // @ts-expect-error — atan2 does not accept a string + const bad = () => Integer.from(1).atan2("nope"); + expect(bad).toThrow(/No matching overload/); +}); + +test("breadth: string / arithmetic / JSON / datetime surface composes", async () => { + // string + const up = Text.from("abc").upper()["||"]("!"); + expect((await conn.execute(sql`SELECT ${up.toSql()} as v`)).rows[0]!["v"]).toBe("ABC!"); + // arithmetic: integer division truncates (typed positions CAST to INTEGER) + const div = Integer.from(7).divide(2); + expect((await conn.execute(sql`SELECT ${div.toSql()} as v`)).rows[0]!["v"]).toBe("3"); + // JSON: jsonExtract honestly returns Any (SQL value of unknown + // class) — numeric methods aren't on Any, so the user asserts + // intent via cast() to keep going. That's the narrow-views model. + const j = Text.from('{"a":{"b":41}}').jsonExtract("$.a.b").cast(Integer).plus(1); + expect((await conn.execute(sql`SELECT ${j.toSql()} as v`)).rows[0]!["v"]).toBe("42"); + // datetime — receiver is the FORMAT string (100% SQL call-order + // fidelity: strftime(format, time, ...) ⇒ format.strftime(time)). + const year = Text.from("%Y").strftime("2025-01-15"); + const r = await conn.execute(sql`SELECT ${year.toSql()} as a`); + expect(r.rows[0]).toEqual({ a: "2025" }); + // comparisons return Bool + const cmp = Integer.from(3).gt(2).and(Bool.from(true)); + expect((await conn.execute(sql`SELECT ${cmp.toSql()} as v`)).rows[0]!["v"]).toBe("1"); +}); + +test("placed methods: wrong-view calls are type errors AND runtime-absent (RPC strictness)", async () => { + // Methods live on the class whose storage class matches their + // receiver argument's documented domain. That curates BOTH gates: TS refuses + // wrong-view calls, and — decisive for RPC callers, who only see + // the prototype — the method simply doesn't exist on the wrong + // view. An Integer stub can't dispatch .upper() at all. + const t = Text.from("x"); + const i = Integer.from(2); + // @ts-expect-error — plus is numeric-only + const _e1 = () => t.plus(1); + // @ts-expect-error — upper is Text-only + const _e2 = () => i.upper(); + // @ts-expect-error — jsonExtract is Text/Blob-only + const _e3 = () => i.jsonExtract("$"); + // Runtime dispatch surface matches the types (prototype placement): + expect((t as any).plus).toBeUndefined(); + expect((i as any).upper).toBeUndefined(); + expect((i as any).jsonExtract).toBeUndefined(); + expect(typeof (i as any).plus).toBe("function"); + // runtime.match rejects wrong-typed args at the gate even on a + // correctly-placed method: + expect(() => (t as any).like(Buffer.from([1]))).toThrow(/No matching overload/); + + // arg0-returns narrow through the generic this (min/max/nullif). + const m = i.max(); + const n = i.nullif(2); + const r = await conn.execute(sql`SELECT ${n.toSql()} as v, ${i.min().toSql()} as w`); + expect(r.rows[0]).toEqual({ v: null, w: "2" }); + // Type-level: nullable variants of the receiver's view, not Any. + const _m: Integer<0 | 1> = m; + const _n: Integer<0 | 1> = n; +}); + +test("numeric binop primitives: integral numbers cast to the claim; fractional reject", async () => { + // TS can't split integral from fractional `number`, so the decl + // accepts any number while claiming Integer. The runtime keeps the + // claim honest: integral operands serialize via a lossless + // CAST(? AS INTEGER); fractional operands fail dispatch instead of + // silently truncating. + const one = Integer.from(1); + const viaPrim = one.minus(2); + const _viaPrim: Integer<1> = viaPrim; + const r1 = await conn.execute(sql`SELECT ${viaPrim.toSql()} as v, typeof(${viaPrim.toSql()}) as t`); + expect(r1.rows[0]).toEqual({ v: "-1", t: "integer" }); + // The compiled SQL carries the forced cast. + const compiled = compile(viaPrim.toSql(), { database: db }); + expect(compiled.text).toContain("CAST(? AS INTEGER)"); + expect(() => (one as any).minus(2.5)).toThrow(/No matching overload/); + + // Cross-type stays honest via instances — distinguishable in TS. + const viaReal = one.minus(Real.from(2.5)); + const _viaReal: Real<1> = viaReal; + const r2 = await conn.execute(sql`SELECT ${viaReal.toSql()} as v, typeof(${viaReal.toSql()}) as t`); + expect(r2.rows[0]).toEqual({ v: "-1.5", t: "real" }); }); test("placeholder emission uses ? not $N", async () => { diff --git a/vitest.config.ts b/vitest.config.ts index 345c0603..cbe6021f 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -39,6 +39,7 @@ export default defineConfig({ exclude: [ "**/node_modules/**", "**/dist/**", + "**/.claude/**", "**/.direnv/**", "**/examples/**", "packages/**",