@vibeorm/sql 5.0.1 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast.d.ts +59 -5
- package/dist/date-truncation.d.ts +27 -0
- package/dist/dialect.d.ts +10 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +300 -208
- package/dist/index.js.map +9 -8
- package/package.json +2 -2
package/dist/ast.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import type { RlsReadinessQuery } from "./dialects/postgres-rls-readiness.ts";
|
|
|
10
10
|
* grows with the runtime in P2/P3. Every shape added here needs a catalog case
|
|
11
11
|
* (tests/catalog/cases.ts) in the same change.
|
|
12
12
|
*/
|
|
13
|
-
import type { AdvisoryLockMode, RlsContextIR, RowLockStrength, RowLockWaitPolicy, ScalarType, SchemaIR, SqlFragmentSpec } from "@vibeorm/schema";
|
|
13
|
+
import type { AdvisoryLockMode, DateTruncationStorage, DateTruncationUnit, RlsContextIR, RowLockStrength, RowLockWaitPolicy, ScalarType, SchemaIR, SqlFragmentSpec } from "@vibeorm/schema";
|
|
14
14
|
/** A column reference, optionally table-qualified. */
|
|
15
15
|
export type ColRef = {
|
|
16
16
|
readonly table?: string;
|
|
@@ -45,6 +45,8 @@ export type ColRef = {
|
|
|
45
45
|
* storage and read-back stay the exact text.
|
|
46
46
|
*/
|
|
47
47
|
readonly castReal?: boolean;
|
|
48
|
+
/** Native enum order key through a scalar subquery: MySQL reads its member index, other dialects keep the column. */
|
|
49
|
+
readonly enumOrdinal?: true;
|
|
48
50
|
/**
|
|
49
51
|
* Order/distinct/compare cast, postgres `json` columns only (`Json @db.Json`,
|
|
50
52
|
* release-3.0 D3): `json` has no ordering or equality operator, so ORDER BY,
|
|
@@ -53,6 +55,17 @@ export type ColRef = {
|
|
|
53
55
|
* column. Never set on projections, so read-back keeps the stored text.
|
|
54
56
|
*/
|
|
55
57
|
readonly castJsonb?: "jsonb" | "jsonb[]";
|
|
58
|
+
/**
|
|
59
|
+
* Calendar truncation of a timestamp column, for a `groupBy` date key. The
|
|
60
|
+
* reference renders as the start of its period in a named time zone
|
|
61
|
+
* (`date_trunc('day', "col", 'Europe/Oslo')`; see `renderDateTruncation`),
|
|
62
|
+
* in the column's own SQL type. Set on the projection, GROUP BY and ORDER BY
|
|
63
|
+
* refs of one key, which then repeat the identical expression text
|
|
64
|
+
* (PostgreSQL matches GROUP BY expressions by structure); a projection keeps
|
|
65
|
+
* `alias ?? name` as its output name. Never set on filter refs. Dialects
|
|
66
|
+
* without the `dateTruncation` capability refuse it when rendering.
|
|
67
|
+
*/
|
|
68
|
+
readonly truncate?: DateTruncation;
|
|
56
69
|
/**
|
|
57
70
|
* Projection alias: renders `ref AS "alias"`. PROJECTION-ONLY — filter,
|
|
58
71
|
* order and correlation refs never set it (the renderer ignores it outside
|
|
@@ -61,6 +74,13 @@ export type ColRef = {
|
|
|
61
74
|
*/
|
|
62
75
|
readonly alias?: string;
|
|
63
76
|
};
|
|
77
|
+
/** A {@link ColRef.truncate} request: the calendar unit, the zone that defines the calendar, and the column's storage form. */
|
|
78
|
+
export type DateTruncation = {
|
|
79
|
+
readonly unit: DateTruncationUnit;
|
|
80
|
+
/** A time-zone name (`"Europe/Oslo"`, `"UTC"`), rendered as a string literal after a strict character check. */
|
|
81
|
+
readonly timeZone: string;
|
|
82
|
+
readonly storage: DateTruncationStorage;
|
|
83
|
+
};
|
|
64
84
|
export type TableRef = {
|
|
65
85
|
readonly name: string;
|
|
66
86
|
/** Explicit fixed PostgreSQL placement; absence preserves existing SQL. */
|
|
@@ -75,6 +95,8 @@ export type AggRef = {
|
|
|
75
95
|
} | {
|
|
76
96
|
readonly fn: AggFn;
|
|
77
97
|
readonly column: ColRef;
|
|
98
|
+
/** Native enum MIN/MAX: projections and HAVING return the database label; order keys keep its ordinal. */
|
|
99
|
+
readonly enumOrder?: "value" | "ordinal";
|
|
78
100
|
};
|
|
79
101
|
/**
|
|
80
102
|
* One aggregate projection: `FN("col") AS "alias"`. The alias is part of the
|
|
@@ -445,18 +467,27 @@ export type OrderByAggregate = {
|
|
|
445
467
|
};
|
|
446
468
|
/**
|
|
447
469
|
* ORDER BY a correlated scalar subquery — relation orderBy
|
|
448
|
-
* (`orderBy: { posts: { _count: "desc" } }` → `(SELECT COUNT(*) …)
|
|
470
|
+
* (`orderBy: { posts: { _count: "desc" } }` → `(SELECT COUNT(*) …)`,
|
|
471
|
+
* `orderBy: { posts: { _max: { createdAt: "desc" } } }` → `(SELECT MAX(…) …)`,
|
|
449
472
|
* `orderBy: { author: { email: "asc" } }` → `(SELECT "email" …)`).
|
|
450
473
|
* Portable: all three dialects order by scalar subqueries. The subquery
|
|
451
474
|
* correlates to the outer scope through table-qualified `cmpCol` predicates,
|
|
452
475
|
* exactly like `exists`; its parameters merge into the statement's single
|
|
453
|
-
* sequence in render order.
|
|
454
|
-
*
|
|
455
|
-
* missing
|
|
476
|
+
* sequence in render order.
|
|
477
|
+
*
|
|
478
|
+
* `nulls` places the NULL a missing to-one row or a parent without related
|
|
479
|
+
* rows (under MIN/MAX/AVG/SUM) sorts as. Without it, NULL sorts at the
|
|
480
|
+
* engine's native position. Postgres and sqlite render `NULLS FIRST|LAST`;
|
|
481
|
+
* mysql renders the bare term when its native placement already matches, and
|
|
482
|
+
* otherwise a leading `(<subquery>) IS NULL` term — the subquery then renders
|
|
483
|
+
* twice and its parameters bind twice, in text order.
|
|
456
484
|
*/
|
|
457
485
|
export type OrderBySubquery = {
|
|
458
486
|
readonly select: SelectStatement;
|
|
487
|
+
/** A count behind a missing to-one row is zero, not NULL. */
|
|
488
|
+
readonly coalesce?: 0;
|
|
459
489
|
readonly direction: "asc" | "desc";
|
|
490
|
+
readonly nulls?: "first" | "last";
|
|
460
491
|
};
|
|
461
492
|
export type OrderTerm = OrderByColumn | OrderByAggregate | OrderBySubquery;
|
|
462
493
|
/**
|
|
@@ -501,6 +532,17 @@ export type LateralJoin = {
|
|
|
501
532
|
/** The correlated child select — may reference outer columns via table-qualified refs. */
|
|
502
533
|
readonly select: SelectStatement;
|
|
503
534
|
};
|
|
535
|
+
/**
|
|
536
|
+
* One scalar subquery in a projection. The builder guarantees a single column
|
|
537
|
+
* and at most one row. Hidden sort values stay inside derived tables rather
|
|
538
|
+
* than becoming result fields. `coalesce` preserves a count across a missing
|
|
539
|
+
* to-one hop.
|
|
540
|
+
*/
|
|
541
|
+
export type ScalarSubquery = {
|
|
542
|
+
readonly alias: string;
|
|
543
|
+
readonly select: SelectStatement;
|
|
544
|
+
readonly coalesce?: 0;
|
|
545
|
+
};
|
|
504
546
|
/**
|
|
505
547
|
* One correlated scalar `COUNT(*)` projected into a select list:
|
|
506
548
|
* `(SELECT COUNT(*) FROM … WHERE <correlation>) AS "alias"` — the relation
|
|
@@ -747,6 +789,8 @@ export type SelectStatement = {
|
|
|
747
789
|
readonly aggregates?: readonly AggSelect[];
|
|
748
790
|
/** Correlated `COUNT(*)` subqueries, rendered after `aggregates` — see {@link CountSubquery}. */
|
|
749
791
|
readonly countSubqueries?: readonly CountSubquery[];
|
|
792
|
+
/** Scalar values projected after count subqueries and before a row number. */
|
|
793
|
+
readonly scalarSubqueries?: readonly ScalarSubquery[];
|
|
750
794
|
/**
|
|
751
795
|
* `SELECT DISTINCT ON (cols)` — postgres only (`capabilities.distinctOn`;
|
|
752
796
|
* other dialects refuse at render time and the runtime emulates client-side
|
|
@@ -969,6 +1013,16 @@ export type OnConflictUpdate = {
|
|
|
969
1013
|
*/
|
|
970
1014
|
readonly conflictWhere?: string;
|
|
971
1015
|
readonly update: Readonly<Record<string, unknown>>;
|
|
1016
|
+
/**
|
|
1017
|
+
* Guard on the update arm, BOUND parameters: `ON CONFLICT (…) DO UPDATE SET
|
|
1018
|
+
* … WHERE <guard>` — the conflicting row is updated (and returned) only when
|
|
1019
|
+
* the guard admits it; otherwise the statement writes and returns nothing.
|
|
1020
|
+
* Postgres has both the target row and `excluded` in scope there, so every
|
|
1021
|
+
* column ref must carry `table` (the target table's name), exactly as the
|
|
1022
|
+
* SET self-references do. Needs the `conflictUpdateWhere` capability:
|
|
1023
|
+
* mysql's ODKU has no WHERE and refuses it (`VIBE_UNSUPPORTED_CAPABILITY`).
|
|
1024
|
+
*/
|
|
1025
|
+
readonly updateWhere?: SqlExpr;
|
|
972
1026
|
/**
|
|
973
1027
|
* MySQL only (`upsertForm: "onDuplicateKey"`): append
|
|
974
1028
|
* `` `col` = LAST_INSERT_ID(`col`) `` to the update list so the UPDATE arm
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { DateTruncation } from "./ast.ts";
|
|
2
|
+
import type { SqlDialect } from "./dialect.ts";
|
|
3
|
+
/** Is this value a time-zone name the renderer will spell as a literal? (See {@link TIME_ZONE_NAME}.) */
|
|
4
|
+
export declare function isTimeZoneName(params: {
|
|
5
|
+
readonly value: unknown;
|
|
6
|
+
}): params is {
|
|
7
|
+
readonly value: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The start of the period that holds `reference`'s value, in the column's own
|
|
11
|
+
* SQL type, so the field's codec decodes it unchanged:
|
|
12
|
+
*
|
|
13
|
+
* - `timestamptz` → `date_trunc('day', "col", 'Europe/Oslo')` — the 3-argument
|
|
14
|
+
* form (PostgreSQL 12 or later) truncates in the named zone, never in the
|
|
15
|
+
* session's `TimeZone`;
|
|
16
|
+
* - `timestamp` (zone-less, UTC wall-clock by contract) →
|
|
17
|
+
* `(date_trunc('day', "col" AT TIME ZONE 'UTC', 'Europe/Oslo') AT TIME ZONE 'UTC')`.
|
|
18
|
+
*
|
|
19
|
+
* The unit and the zone are literals, so every site of one key (projection,
|
|
20
|
+
* GROUP BY, ORDER BY) repeats the identical text and binds no parameter.
|
|
21
|
+
*/
|
|
22
|
+
export declare function renderDateTruncation(params: {
|
|
23
|
+
readonly dialect: SqlDialect;
|
|
24
|
+
readonly reference: string;
|
|
25
|
+
readonly truncation: DateTruncation;
|
|
26
|
+
}): string;
|
|
27
|
+
//# sourceMappingURL=date-truncation.d.ts.map
|
package/dist/dialect.d.ts
CHANGED
|
@@ -446,6 +446,16 @@ export type SqlDialect = {
|
|
|
446
446
|
quoteStringLiteral(params: {
|
|
447
447
|
value: string;
|
|
448
448
|
}): string;
|
|
449
|
+
/** Keep a native enum's ordering through a scalar subquery that may lose its physical enum type. */
|
|
450
|
+
renderEnumOrdinal(params: {
|
|
451
|
+
column: string;
|
|
452
|
+
}): string;
|
|
453
|
+
/** Render native enum MIN/MAX in database declaration order, returning its label or an order key. */
|
|
454
|
+
renderEnumMinMax(params: {
|
|
455
|
+
fn: "min" | "max";
|
|
456
|
+
column: string;
|
|
457
|
+
result: "value" | "ordinal";
|
|
458
|
+
}): string;
|
|
449
459
|
/** Positional placeholder for the 1-based parameter index ($n or ?). */
|
|
450
460
|
placeholder(params: {
|
|
451
461
|
index: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export type { ResultDecoder, ResultReadDecoder, ResultParameterEncoder, ResultSc
|
|
|
40
40
|
* lives in this package; see the root sql-catalog.md for the reviewable surface.
|
|
41
41
|
*/
|
|
42
42
|
export { compileExclusion, renderExclusionSetup, renderExclusionDdl, renderExclusionCatalog, renderExclusionProbe } from "./exclusion.ts";
|
|
43
|
-
export type { AdvisoryLockKey, AdvisoryLockStatement, AggFn, AggRef, AggSelect, ChainResult, ChainRowSource, ChainStatement, ChainStep, ChainStepStatement, ChainTally, ChainVeto, ColRef, ComparisonOp, CountSubquery, DeleteStatement, ExcludedRef, InnerJoin, KeyListMember, KeyPage, KeyRows, KeyTableJoin, KeyTableMember, InsertSelectStatement, InsertStatement, ReturningColumn, JsonFilterOp, LateralJoin, LeftJoin, ListSetOperation, OnConflictClause, OnConflictDoNothing, OnConflictUpdate, OrderByAggregate, OrderByColumn, OrderBySubquery, OrderTerm, RowLock, RowNumberProjection, DbNowMarker, JsonParamCell, SelectExpr, SelectStatement, SetOperation, SetOperator, SqlExpr, SqlStatement, StepColumnRef, TableRef, UpdateStatement, } from "./ast.ts";
|
|
43
|
+
export type { AdvisoryLockKey, AdvisoryLockStatement, AggFn, AggRef, AggSelect, ChainResult, ChainRowSource, ChainStatement, ChainStep, ChainStepStatement, ChainTally, ChainVeto, ColRef, ComparisonOp, DateTruncation, CountSubquery, ScalarSubquery, DeleteStatement, ExcludedRef, InnerJoin, KeyListMember, KeyPage, KeyRows, KeyTableJoin, KeyTableMember, InsertSelectStatement, InsertStatement, ReturningColumn, JsonFilterOp, LateralJoin, LeftJoin, ListSetOperation, OnConflictClause, OnConflictDoNothing, OnConflictUpdate, OrderByAggregate, OrderByColumn, OrderBySubquery, OrderTerm, RowLock, RowNumberProjection, DbNowMarker, JsonParamCell, SelectExpr, SelectStatement, SetOperation, SetOperator, SqlExpr, SqlStatement, StepColumnRef, TableRef, UpdateStatement, } from "./ast.ts";
|
|
44
44
|
export { ADVISORY_LOCK_RESULT_COLUMN, CHAIN_VETO_PREFIX, CHAIN_VETO_TOKEN_PATTERN, SQL_DEFAULT_CELL, SQL_KEEP_CELL, chainVetoToken, dbNowMarker, excludedRef, isDbNowMarker, isExcludedRef, isJsonParamCell, isListSetOperation, isSetOperation, isSqlDefaultCell, isSqlKeepCell, isStepColumnRef, jsonParamCell, returningColumnName, stepColumnRef, } from "./ast.ts";
|
|
45
45
|
export type { AdvisoryLockFunctions, AdvisoryLockModeFunctions, RowLockSyntax, EmptyInsertSyntax, SqlDialect, } from "./dialect.ts";
|
|
46
46
|
export { ADVISORY_KEY_BOUNDS, describeRowLock, renderAdvisoryLock, renderRowLockClause } from "./locks.ts";
|
|
@@ -53,6 +53,7 @@ export { tableDefinitionParts } from "./dialects/sqlite-table-definition.ts";
|
|
|
53
53
|
export { keyListBindsUntypedRows, postgresBulkInsertArrayCastOf, postgresKeyListElementTypeOf } from "./key-list.ts";
|
|
54
54
|
export { renderPredicate, renderSchemaExpression } from "./predicate.ts";
|
|
55
55
|
export { renderLocalDateCheck } from "./local-date.ts";
|
|
56
|
+
export { isTimeZoneName, renderDateTruncation } from "./date-truncation.ts";
|
|
56
57
|
export { renderGeneratedColumnClause } from "./generated-columns.ts";
|
|
57
58
|
export type { GeneratedColumnDeclaration, ExtractedGeneratedColumn } from "./generated-columns.ts";
|
|
58
59
|
export { renderPostgresGeneratedColumnProbe, renderPostgresDropGeneratedExpression } from "./dialects/postgres-generated-columns.ts";
|