metal-orm 1.1.23 → 1.1.25
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/index.cjs +832 -583
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +281 -144
- package/dist/index.d.ts +281 -144
- package/dist/index.js +807 -583
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/dialect/base/returning-strategy.ts +40 -39
- package/src/core/dialect/base/sql-compiler-set.ts +33 -0
- package/src/core/dialect/base/sql-dialect.ts +125 -222
- package/src/core/dialect/base/standard-delete-compiler.ts +37 -0
- package/src/core/dialect/base/standard-insert-compiler.ts +49 -0
- package/src/core/dialect/base/standard-select-compiler.ts +82 -0
- package/src/core/dialect/base/standard-sql-services.ts +44 -0
- package/src/core/dialect/base/standard-sql-source-compiler.ts +88 -0
- package/src/core/dialect/base/standard-update-compiler.ts +53 -0
- package/src/core/dialect/base/upsert-strategy.ts +45 -0
- package/src/core/dialect/capabilities/procedure-compiler.ts +10 -8
- package/src/core/dialect/mssql/compiler-factory.ts +12 -0
- package/src/core/dialect/mssql/delete-compiler.ts +40 -0
- package/src/core/dialect/mssql/index.ts +24 -371
- package/src/core/dialect/mssql/insert-compiler.ts +112 -0
- package/src/core/dialect/mssql/output.ts +46 -0
- package/src/core/dialect/mssql/procedure-compiler.ts +81 -0
- package/src/core/dialect/mssql/select-compiler.ts +116 -0
- package/src/core/dialect/mssql/update-compiler.ts +37 -0
- package/src/core/dialect/mysql/index.ts +24 -117
- package/src/core/dialect/mysql/procedure-compiler.ts +67 -0
- package/src/core/dialect/mysql/upsert.ts +42 -0
- package/src/core/dialect/postgres/index.ts +34 -101
- package/src/core/dialect/postgres/procedure-compiler.ts +41 -0
- package/src/core/dialect/postgres/returning.ts +4 -0
- package/src/core/dialect/postgres/upsert.ts +43 -0
- package/src/core/dialect/sqlite/index.ts +15 -70
- package/src/core/dialect/sqlite/returning.ts +30 -0
- package/src/core/dialect/sqlite/upsert.ts +43 -0
- package/src/index.ts +28 -10
package/dist/index.js
CHANGED
|
@@ -1686,6 +1686,57 @@ var DialectBase = class _DialectBase {
|
|
|
1686
1686
|
}
|
|
1687
1687
|
};
|
|
1688
1688
|
|
|
1689
|
+
// src/core/dialect/base/pagination-strategy.ts
|
|
1690
|
+
var StandardLimitOffsetPagination = class {
|
|
1691
|
+
/**
|
|
1692
|
+
* Compiles LIMIT/OFFSET pagination clause.
|
|
1693
|
+
* @param limit - The maximum number of rows to return.
|
|
1694
|
+
* @param offset - The number of rows to skip.
|
|
1695
|
+
* @returns SQL pagination clause with LIMIT and/or OFFSET.
|
|
1696
|
+
*/
|
|
1697
|
+
compilePagination(limit, offset) {
|
|
1698
|
+
const parts = [];
|
|
1699
|
+
if (limit !== void 0) parts.push(`LIMIT ${limit}`);
|
|
1700
|
+
if (offset !== void 0) parts.push(`OFFSET ${offset}`);
|
|
1701
|
+
return parts.length ? ` ${parts.join(" ")}` : "";
|
|
1702
|
+
}
|
|
1703
|
+
};
|
|
1704
|
+
|
|
1705
|
+
// src/core/dialect/base/returning-strategy.ts
|
|
1706
|
+
var NoReturningStrategy = class {
|
|
1707
|
+
compileReturning(returning, _ctx, _quoteIdentifier) {
|
|
1708
|
+
void _ctx;
|
|
1709
|
+
void _quoteIdentifier;
|
|
1710
|
+
if (!returning || returning.length === 0) return "";
|
|
1711
|
+
throw new Error("RETURNING is not supported by this dialect.");
|
|
1712
|
+
}
|
|
1713
|
+
formatReturningColumns(returning, quoteIdentifier) {
|
|
1714
|
+
return returning.map((column) => {
|
|
1715
|
+
const tablePart = column.table ? `${quoteIdentifier(column.table)}.` : "";
|
|
1716
|
+
const aliasPart = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : "";
|
|
1717
|
+
return `${tablePart}${quoteIdentifier(column.name)}${aliasPart}`;
|
|
1718
|
+
}).join(", ");
|
|
1719
|
+
}
|
|
1720
|
+
};
|
|
1721
|
+
var StandardReturningStrategy = class extends NoReturningStrategy {
|
|
1722
|
+
compileReturning(returning, _ctx, quoteIdentifier) {
|
|
1723
|
+
void _ctx;
|
|
1724
|
+
if (!returning || returning.length === 0) return "";
|
|
1725
|
+
return ` RETURNING ${this.formatReturningColumns(returning, quoteIdentifier)}`;
|
|
1726
|
+
}
|
|
1727
|
+
};
|
|
1728
|
+
|
|
1729
|
+
// src/core/dialect/base/upsert-strategy.ts
|
|
1730
|
+
var NoUpsertStrategy = class {
|
|
1731
|
+
compile(ast, _ctx, services) {
|
|
1732
|
+
void _ctx;
|
|
1733
|
+
if (!ast.onConflict) return "";
|
|
1734
|
+
throw new Error(
|
|
1735
|
+
`UPSERT/ON CONFLICT is not supported by dialect "${services.getDialectName()}".`
|
|
1736
|
+
);
|
|
1737
|
+
}
|
|
1738
|
+
};
|
|
1739
|
+
|
|
1689
1740
|
// src/core/dialect/base/function-table-formatter.ts
|
|
1690
1741
|
var FunctionTableFormatter = class {
|
|
1691
1742
|
static format(fn9, ctx, formatter) {
|
|
@@ -1722,19 +1773,71 @@ var FunctionTableFormatter = class {
|
|
|
1722
1773
|
}
|
|
1723
1774
|
};
|
|
1724
1775
|
|
|
1725
|
-
// src/core/dialect/base/
|
|
1726
|
-
var
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1776
|
+
// src/core/dialect/base/standard-sql-source-compiler.ts
|
|
1777
|
+
var StandardSqlSourceCompiler = class {
|
|
1778
|
+
constructor(services) {
|
|
1779
|
+
this.services = services;
|
|
1780
|
+
}
|
|
1781
|
+
compileFrom(source, ctx) {
|
|
1782
|
+
if (source.type === "FunctionTable") return this.compileFunctionTable(source, ctx);
|
|
1783
|
+
if (source.type === "DerivedTable") return this.compileDerivedTable(source, ctx);
|
|
1784
|
+
return this.compileTableSource(source);
|
|
1785
|
+
}
|
|
1786
|
+
compileFunctionTable(fn9, ctx) {
|
|
1787
|
+
const key = fn9.key ?? fn9.name;
|
|
1788
|
+
if (ctx) {
|
|
1789
|
+
const renderer = this.services.getTableFunctionStrategy().getRenderer(key);
|
|
1790
|
+
if (renderer) {
|
|
1791
|
+
const compiledArgs = (fn9.args ?? []).map((arg) => this.services.compileOperand(arg, ctx));
|
|
1792
|
+
return renderer({
|
|
1793
|
+
node: fn9,
|
|
1794
|
+
compiledArgs,
|
|
1795
|
+
compileOperand: (operand) => this.services.compileOperand(operand, ctx),
|
|
1796
|
+
quoteIdentifier: (id) => this.services.quoteIdentifier(id)
|
|
1797
|
+
});
|
|
1798
|
+
}
|
|
1799
|
+
if (fn9.key) {
|
|
1800
|
+
throw new Error(
|
|
1801
|
+
`Table function "${key}" is not supported by dialect "${this.services.getDialectName()}".`
|
|
1802
|
+
);
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
return FunctionTableFormatter.format(fn9, ctx, {
|
|
1806
|
+
quoteIdentifier: (id) => this.services.quoteIdentifier(id),
|
|
1807
|
+
compileOperand: (node, compilerContext) => this.services.compileOperand(node, compilerContext)
|
|
1808
|
+
});
|
|
1809
|
+
}
|
|
1810
|
+
compileDerivedTable(table, ctx) {
|
|
1811
|
+
if (!table.alias) throw new Error("Derived tables must have an alias.");
|
|
1812
|
+
if (!ctx) throw new Error("Derived table compilation requires a compiler context.");
|
|
1813
|
+
const normalized = this.services.normalizeSelectAst(table.query);
|
|
1814
|
+
const subquery = this.services.compileSelectAst(normalized, ctx).trim().replace(/;$/, "");
|
|
1815
|
+
const columns = table.columnAliases?.length ? ` (${table.columnAliases.map((column) => this.services.quoteIdentifier(column)).join(", ")})` : "";
|
|
1816
|
+
return `(${subquery}) AS ${this.services.quoteIdentifier(table.alias)}${columns}`;
|
|
1817
|
+
}
|
|
1818
|
+
compileTableSource(table) {
|
|
1819
|
+
if (table.type === "FunctionTable") return this.compileFunctionTable(table);
|
|
1820
|
+
if (table.type === "DerivedTable") {
|
|
1821
|
+
throw new Error("Derived table compilation requires a compiler context.");
|
|
1822
|
+
}
|
|
1823
|
+
const base = this.compileTableName(table);
|
|
1824
|
+
return table.alias ? `${base} AS ${this.services.quoteIdentifier(table.alias)}` : base;
|
|
1825
|
+
}
|
|
1826
|
+
compileTableName(table) {
|
|
1827
|
+
if (table.schema) {
|
|
1828
|
+
return `${this.services.quoteIdentifier(table.schema)}.${this.services.quoteIdentifier(table.name)}`;
|
|
1829
|
+
}
|
|
1830
|
+
return this.services.quoteIdentifier(table.name);
|
|
1831
|
+
}
|
|
1832
|
+
compileTableReference(table) {
|
|
1833
|
+
const base = this.compileTableName(table);
|
|
1834
|
+
return table.alias ? `${base} AS ${this.services.quoteIdentifier(table.alias)}` : base;
|
|
1835
|
+
}
|
|
1836
|
+
stripTrailingSemicolon(sql) {
|
|
1837
|
+
return sql.trim().replace(/;$/, "");
|
|
1838
|
+
}
|
|
1839
|
+
wrapSetOperand(sql) {
|
|
1840
|
+
return `(${this.stripTrailingSemicolon(sql)})`;
|
|
1738
1841
|
}
|
|
1739
1842
|
};
|
|
1740
1843
|
|
|
@@ -1764,34 +1867,6 @@ var CteCompiler = class {
|
|
|
1764
1867
|
}
|
|
1765
1868
|
};
|
|
1766
1869
|
|
|
1767
|
-
// src/core/dialect/base/returning-strategy.ts
|
|
1768
|
-
var NoReturningStrategy = class {
|
|
1769
|
-
/**
|
|
1770
|
-
* Throws an error as RETURNING is not supported.
|
|
1771
|
-
* @param returning - Columns to return (causes error if non-empty).
|
|
1772
|
-
* @param _ctx - Compiler context (unused).
|
|
1773
|
-
* @throws Error indicating RETURNING is not supported.
|
|
1774
|
-
*/
|
|
1775
|
-
compileReturning(returning, _ctx) {
|
|
1776
|
-
void _ctx;
|
|
1777
|
-
if (!returning || returning.length === 0) return "";
|
|
1778
|
-
throw new Error("RETURNING is not supported by this dialect.");
|
|
1779
|
-
}
|
|
1780
|
-
/**
|
|
1781
|
-
* Formats column names for RETURNING clause.
|
|
1782
|
-
* @param returning - Columns to format.
|
|
1783
|
-
* @param quoteIdentifier - Function to quote identifiers according to dialect rules.
|
|
1784
|
-
* @returns Simple comma-separated column names.
|
|
1785
|
-
*/
|
|
1786
|
-
formatReturningColumns(returning, quoteIdentifier) {
|
|
1787
|
-
return returning.map((column) => {
|
|
1788
|
-
const tablePart = column.table ? `${quoteIdentifier(column.table)}.` : "";
|
|
1789
|
-
const aliasPart = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : "";
|
|
1790
|
-
return `${tablePart}${quoteIdentifier(column.name)}${aliasPart}`;
|
|
1791
|
-
}).join(", ");
|
|
1792
|
-
}
|
|
1793
|
-
};
|
|
1794
|
-
|
|
1795
1870
|
// src/core/dialect/base/join-compiler.ts
|
|
1796
1871
|
var JoinCompiler = class {
|
|
1797
1872
|
static compileJoins(joins, ctx, compileFrom, compileExpression) {
|
|
@@ -1842,108 +1917,254 @@ var OrderByCompiler = class {
|
|
|
1842
1917
|
}
|
|
1843
1918
|
};
|
|
1844
1919
|
|
|
1845
|
-
// src/core/dialect/base/
|
|
1846
|
-
var
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1920
|
+
// src/core/dialect/base/standard-select-compiler.ts
|
|
1921
|
+
var StandardSelectCompiler = class {
|
|
1922
|
+
constructor(services, sources) {
|
|
1923
|
+
this.services = services;
|
|
1924
|
+
this.sources = sources;
|
|
1925
|
+
}
|
|
1926
|
+
compile(ast, ctx) {
|
|
1850
1927
|
const hasSetOps = !!(ast.setOps && ast.setOps.length);
|
|
1851
1928
|
const ctes = CteCompiler.compileCtes(
|
|
1852
1929
|
ast,
|
|
1853
1930
|
ctx,
|
|
1854
|
-
this.quoteIdentifier
|
|
1855
|
-
this.compileSelectAst
|
|
1856
|
-
this.normalizeSelectAst
|
|
1857
|
-
this.stripTrailingSemicolon
|
|
1931
|
+
(id) => this.services.quoteIdentifier(id),
|
|
1932
|
+
(query, compilerContext) => this.services.compileSelectAst(query, compilerContext),
|
|
1933
|
+
(query) => this.services.normalizeSelectAst(query),
|
|
1934
|
+
(sql) => this.sources.stripTrailingSemicolon(sql)
|
|
1858
1935
|
);
|
|
1859
1936
|
const baseAst = hasSetOps ? { ...ast, setOps: void 0, orderBy: void 0, limit: void 0, offset: void 0 } : ast;
|
|
1860
|
-
const baseSelect = this.
|
|
1937
|
+
const baseSelect = this.compileCore(baseAst, ctx);
|
|
1861
1938
|
if (!hasSetOps) return `${ctes}${baseSelect}`;
|
|
1862
|
-
|
|
1939
|
+
const compound = ast.setOps.map((op) => `${op.operator} ${this.sources.wrapSetOperand(this.services.compileSelectAst(op.query, ctx))}`).join(" ");
|
|
1940
|
+
const orderBy = this.compileOrderBy(ast, ctx);
|
|
1941
|
+
const pagination = this.services.getPaginationStrategy().compilePagination(ast.limit, ast.offset);
|
|
1942
|
+
const combined = `${this.sources.wrapSetOperand(baseSelect)} ${compound}`;
|
|
1943
|
+
return `${ctes}${combined}${orderBy}${pagination}`;
|
|
1944
|
+
}
|
|
1945
|
+
compileCore(ast, ctx) {
|
|
1946
|
+
const columns = this.compileColumns(ast, ctx);
|
|
1947
|
+
const from = this.sources.compileFrom(ast.from, ctx);
|
|
1948
|
+
const joins = JoinCompiler.compileJoins(
|
|
1949
|
+
ast.joins,
|
|
1950
|
+
ctx,
|
|
1951
|
+
(source, compilerContext) => this.sources.compileFrom(source, compilerContext),
|
|
1952
|
+
(expression, compilerContext) => this.services.compileExpression(expression, compilerContext)
|
|
1953
|
+
);
|
|
1954
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
1955
|
+
const groupBy = GroupByCompiler.compileGroupBy(
|
|
1956
|
+
ast,
|
|
1957
|
+
(term) => this.services.compileOrderingTerm(term, ctx)
|
|
1958
|
+
);
|
|
1959
|
+
const having = ast.having ? ` HAVING ${this.services.compileExpression(ast.having, ctx)}` : "";
|
|
1960
|
+
const orderBy = this.compileOrderBy(ast, ctx);
|
|
1961
|
+
const pagination = this.services.getPaginationStrategy().compilePagination(ast.limit, ast.offset);
|
|
1962
|
+
return `SELECT ${ast.distinct ? "DISTINCT " : ""}${columns} FROM ${from}${joins}${where}${groupBy}${having}${orderBy}${pagination}`;
|
|
1863
1963
|
}
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1964
|
+
compileColumns(ast, ctx) {
|
|
1965
|
+
if (!ast.columns || ast.columns.length === 0) return "*";
|
|
1966
|
+
return ast.columns.map((column) => {
|
|
1967
|
+
const expr = this.services.compileOperand(column, ctx);
|
|
1968
|
+
if (!column.alias) return expr;
|
|
1969
|
+
if (column.alias.includes("(")) return column.alias;
|
|
1970
|
+
return `${expr} AS ${this.services.quoteIdentifier(column.alias)}`;
|
|
1971
|
+
}).join(", ");
|
|
1972
|
+
}
|
|
1973
|
+
compileOrderBy(ast, ctx) {
|
|
1974
|
+
return OrderByCompiler.compileOrderBy(
|
|
1867
1975
|
ast,
|
|
1868
|
-
(term) => this.compileOrderingTerm(term, ctx),
|
|
1869
|
-
this.renderOrderByNulls
|
|
1870
|
-
this.renderOrderByCollation
|
|
1976
|
+
(term) => this.services.compileOrderingTerm(term, ctx),
|
|
1977
|
+
(order) => this.services.renderOrderByNulls(order),
|
|
1978
|
+
(order) => this.services.renderOrderByCollation(order)
|
|
1871
1979
|
);
|
|
1872
|
-
const pagination = this.paginationStrategy.compilePagination(ast.limit, ast.offset);
|
|
1873
|
-
const combined = `${this.wrapSetOperand(baseSelect)} ${compound}`;
|
|
1874
|
-
return `${ctes}${combined}${orderBy}${pagination}`;
|
|
1875
1980
|
}
|
|
1876
|
-
|
|
1981
|
+
};
|
|
1982
|
+
|
|
1983
|
+
// src/core/dialect/base/standard-insert-compiler.ts
|
|
1984
|
+
var StandardInsertCompiler = class {
|
|
1985
|
+
constructor(services, sources) {
|
|
1986
|
+
this.services = services;
|
|
1987
|
+
this.sources = sources;
|
|
1988
|
+
}
|
|
1989
|
+
compile(ast, ctx) {
|
|
1877
1990
|
if (!ast.columns.length) {
|
|
1878
1991
|
throw new Error("INSERT queries must specify columns.");
|
|
1879
1992
|
}
|
|
1880
|
-
const table = this.compileTableName(ast.into);
|
|
1881
|
-
const columnList = this.
|
|
1882
|
-
const source = this.
|
|
1883
|
-
const upsert = this.compileUpsertClause(ast, ctx);
|
|
1884
|
-
const returning = this.compileReturning(ast.returning, ctx);
|
|
1993
|
+
const table = this.sources.compileTableName(ast.into);
|
|
1994
|
+
const columnList = this.compileColumnList(ast.columns);
|
|
1995
|
+
const source = this.compileSource(ast.source, ctx);
|
|
1996
|
+
const upsert = this.services.compileUpsertClause(ast, ctx);
|
|
1997
|
+
const returning = this.services.compileReturning(ast.returning, ctx);
|
|
1885
1998
|
return `INSERT INTO ${table} (${columnList}) ${source}${upsert}${returning}`;
|
|
1886
1999
|
}
|
|
1887
|
-
|
|
1888
|
-
void _ctx;
|
|
1889
|
-
if (!ast.onConflict) return "";
|
|
1890
|
-
throw new Error(`UPSERT/ON CONFLICT is not supported by dialect "${this.dialect}".`);
|
|
1891
|
-
}
|
|
1892
|
-
compileReturning(returning, ctx) {
|
|
1893
|
-
return this.returningStrategy.compileReturning(returning, ctx);
|
|
1894
|
-
}
|
|
1895
|
-
compileInsertSource(source, ctx) {
|
|
2000
|
+
compileSource(source, ctx) {
|
|
1896
2001
|
if (source.type === "InsertValues") {
|
|
1897
2002
|
if (!source.rows.length) {
|
|
1898
2003
|
throw new Error("INSERT ... VALUES requires at least one row.");
|
|
1899
2004
|
}
|
|
1900
|
-
const values = source.rows.map((row) => `(${row.map((value) => this.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
2005
|
+
const values = source.rows.map((row) => `(${row.map((value) => this.services.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
1901
2006
|
return `VALUES ${values}`;
|
|
1902
2007
|
}
|
|
1903
|
-
const normalized = this.normalizeSelectAst(source.query);
|
|
1904
|
-
return this.compileSelectAst(normalized, ctx).trim();
|
|
2008
|
+
const normalized = this.services.normalizeSelectAst(source.query);
|
|
2009
|
+
return this.services.compileSelectAst(normalized, ctx).trim();
|
|
1905
2010
|
}
|
|
1906
|
-
|
|
1907
|
-
return columns.map((column) => this.quoteIdentifier(column.name)).join(", ");
|
|
2011
|
+
compileColumnList(columns) {
|
|
2012
|
+
return columns.map((column) => this.services.quoteIdentifier(column.name)).join(", ");
|
|
1908
2013
|
}
|
|
1909
2014
|
ensureConflictColumns(clause, message) {
|
|
1910
2015
|
if (!clause.target.columns.length) throw new Error(message);
|
|
1911
2016
|
}
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
2017
|
+
};
|
|
2018
|
+
|
|
2019
|
+
// src/core/dialect/base/standard-update-compiler.ts
|
|
2020
|
+
var StandardUpdateCompiler = class {
|
|
2021
|
+
constructor(services, sources) {
|
|
2022
|
+
this.services = services;
|
|
2023
|
+
this.sources = sources;
|
|
2024
|
+
}
|
|
2025
|
+
compile(ast, ctx) {
|
|
2026
|
+
const target = this.sources.compileTableReference(ast.table);
|
|
2027
|
+
const assignments = this.compileAssignments(ast.set, ast.table, ctx);
|
|
2028
|
+
const from = this.compileFromClause(ast, ctx);
|
|
2029
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
2030
|
+
const returning = this.services.compileReturning(ast.returning, ctx);
|
|
2031
|
+
return `UPDATE ${target} SET ${assignments}${from}${where}${returning}`;
|
|
2032
|
+
}
|
|
2033
|
+
compileAssignments(assignments, table, ctx) {
|
|
2034
|
+
return assignments.map((assignment) => {
|
|
2035
|
+
const target = this.services.compileSetTarget(assignment.column, table);
|
|
2036
|
+
const value = this.services.compileOperand(assignment.value, ctx);
|
|
2037
|
+
return `${target} = ${value}`;
|
|
2038
|
+
}).join(", ");
|
|
2039
|
+
}
|
|
2040
|
+
compileFromClause(ast, ctx) {
|
|
2041
|
+
if (!ast.from && (!ast.joins || ast.joins.length === 0)) return "";
|
|
2042
|
+
if (!ast.from) {
|
|
2043
|
+
throw new Error("UPDATE with JOINs requires an explicit FROM clause.");
|
|
2044
|
+
}
|
|
2045
|
+
const from = this.sources.compileFrom(ast.from, ctx);
|
|
1915
2046
|
const joins = JoinCompiler.compileJoins(
|
|
1916
2047
|
ast.joins,
|
|
1917
2048
|
ctx,
|
|
1918
|
-
this.compileFrom
|
|
1919
|
-
this.compileExpression
|
|
2049
|
+
(source, compilerContext) => this.sources.compileFrom(source, compilerContext),
|
|
2050
|
+
(expression, compilerContext) => this.services.compileExpression(expression, compilerContext)
|
|
1920
2051
|
);
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
2052
|
+
return ` FROM ${from}${joins}`;
|
|
2053
|
+
}
|
|
2054
|
+
};
|
|
2055
|
+
|
|
2056
|
+
// src/core/dialect/base/standard-delete-compiler.ts
|
|
2057
|
+
var StandardDeleteCompiler = class {
|
|
2058
|
+
constructor(services, sources) {
|
|
2059
|
+
this.services = services;
|
|
2060
|
+
this.sources = sources;
|
|
2061
|
+
}
|
|
2062
|
+
compile(ast, ctx) {
|
|
2063
|
+
const target = this.sources.compileTableReference(ast.from);
|
|
2064
|
+
const using = this.compileUsingClause(ast, ctx);
|
|
2065
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
2066
|
+
const returning = this.services.compileReturning(ast.returning, ctx);
|
|
2067
|
+
return `DELETE FROM ${target}${using}${where}${returning}`;
|
|
2068
|
+
}
|
|
2069
|
+
compileUsingClause(ast, ctx) {
|
|
2070
|
+
if (!ast.using && (!ast.joins || ast.joins.length === 0)) return "";
|
|
2071
|
+
if (!ast.using) {
|
|
2072
|
+
throw new Error("DELETE with JOINs requires a USING clause.");
|
|
2073
|
+
}
|
|
2074
|
+
const usingTable = this.sources.compileFrom(ast.using, ctx);
|
|
2075
|
+
const joins = JoinCompiler.compileJoins(
|
|
2076
|
+
ast.joins,
|
|
2077
|
+
ctx,
|
|
2078
|
+
(source, compilerContext) => this.sources.compileFrom(source, compilerContext),
|
|
2079
|
+
(expression, compilerContext) => this.services.compileExpression(expression, compilerContext)
|
|
1929
2080
|
);
|
|
1930
|
-
|
|
1931
|
-
|
|
2081
|
+
return ` USING ${usingTable}${joins}`;
|
|
2082
|
+
}
|
|
2083
|
+
};
|
|
2084
|
+
|
|
2085
|
+
// src/core/dialect/base/sql-dialect.ts
|
|
2086
|
+
var SqlDialectBase = class extends DialectBase {
|
|
2087
|
+
paginationStrategy;
|
|
2088
|
+
returningStrategy;
|
|
2089
|
+
upsertStrategy;
|
|
2090
|
+
dmlReturningSupported;
|
|
2091
|
+
sourceCompiler;
|
|
2092
|
+
standardUpdateCompiler;
|
|
2093
|
+
compilerSet;
|
|
2094
|
+
constructor(options = {}) {
|
|
2095
|
+
super(options.functionStrategy, options.tableFunctionStrategy);
|
|
2096
|
+
this.paginationStrategy = options.paginationStrategy ?? new StandardLimitOffsetPagination();
|
|
2097
|
+
this.returningStrategy = options.returningStrategy ?? new NoReturningStrategy();
|
|
2098
|
+
this.upsertStrategy = options.upsertStrategy ?? new NoUpsertStrategy();
|
|
2099
|
+
this.dmlReturningSupported = options.supportsDmlReturning ?? false;
|
|
2100
|
+
const services = {
|
|
2101
|
+
getDialectName: () => this.dialect,
|
|
2102
|
+
getPaginationStrategy: () => this.paginationStrategy,
|
|
2103
|
+
getTableFunctionStrategy: () => this.tableFunctionStrategy,
|
|
2104
|
+
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
2105
|
+
compileOperand: (node, ctx) => this.compileOperand(node, ctx),
|
|
2106
|
+
compileExpression: (node, ctx) => this.compileExpression(node, ctx),
|
|
2107
|
+
compileOrderingTerm: (term, ctx) => this.compileOrderingTerm(term, ctx),
|
|
2108
|
+
normalizeSelectAst: (ast) => this.normalizeSelectAst(ast),
|
|
2109
|
+
compileSelectAst: (ast, ctx) => this.compileSelectAst(ast, ctx),
|
|
2110
|
+
compileReturning: (returning, ctx) => this.compileReturning(returning, ctx),
|
|
2111
|
+
compileUpsertClause: (ast, ctx) => this.compileUpsertClause(ast, ctx),
|
|
2112
|
+
compileSetTarget: (column, table) => this.compileSetTarget(column, table),
|
|
2113
|
+
renderOrderByNulls: (order) => this.renderOrderByNulls(order),
|
|
2114
|
+
renderOrderByCollation: (order) => this.renderOrderByCollation(order)
|
|
2115
|
+
};
|
|
2116
|
+
this.sourceCompiler = new StandardSqlSourceCompiler(services);
|
|
2117
|
+
const standardSelect = new StandardSelectCompiler(services, this.sourceCompiler);
|
|
2118
|
+
const standardInsert = new StandardInsertCompiler(services, this.sourceCompiler);
|
|
2119
|
+
this.standardUpdateCompiler = new StandardUpdateCompiler(services, this.sourceCompiler);
|
|
2120
|
+
const standardDelete = new StandardDeleteCompiler(services, this.sourceCompiler);
|
|
2121
|
+
const overrides = options.compilerFactory?.({
|
|
2122
|
+
services,
|
|
2123
|
+
sources: this.sourceCompiler
|
|
2124
|
+
}) ?? {};
|
|
2125
|
+
this.compilerSet = {
|
|
2126
|
+
select: overrides.select ?? standardSelect,
|
|
2127
|
+
insert: overrides.insert ?? standardInsert,
|
|
2128
|
+
update: overrides.update ?? this.standardUpdateCompiler,
|
|
2129
|
+
delete: overrides.delete ?? standardDelete
|
|
2130
|
+
};
|
|
2131
|
+
}
|
|
2132
|
+
supportsDmlReturningClause() {
|
|
2133
|
+
return this.dmlReturningSupported;
|
|
2134
|
+
}
|
|
2135
|
+
compileSelectAst(ast, ctx) {
|
|
2136
|
+
return this.compilerSet.select.compile(ast, ctx);
|
|
2137
|
+
}
|
|
2138
|
+
compileInsertAst(ast, ctx) {
|
|
2139
|
+
return this.compilerSet.insert.compile(ast, ctx);
|
|
1932
2140
|
}
|
|
1933
2141
|
compileUpdateAst(ast, ctx) {
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
2142
|
+
return this.compilerSet.update.compile(ast, ctx);
|
|
2143
|
+
}
|
|
2144
|
+
compileDeleteAst(ast, ctx) {
|
|
2145
|
+
return this.compilerSet.delete.compile(ast, ctx);
|
|
2146
|
+
}
|
|
2147
|
+
compileUpsertClause(ast, ctx) {
|
|
2148
|
+
return this.upsertStrategy.compile(ast, ctx, {
|
|
2149
|
+
getDialectName: () => this.dialect,
|
|
2150
|
+
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
2151
|
+
compileOperand: (node, compilerContext) => this.compileOperand(node, compilerContext),
|
|
2152
|
+
compileExpression: (node, compilerContext) => this.compileExpression(node, compilerContext),
|
|
2153
|
+
compileUpdateAssignments: (assignments, table, compilerContext) => this.standardUpdateCompiler.compileAssignments(assignments, table, compilerContext)
|
|
2154
|
+
});
|
|
2155
|
+
}
|
|
2156
|
+
compileReturning(returning, ctx) {
|
|
2157
|
+
return this.returningStrategy.compileReturning(
|
|
2158
|
+
returning,
|
|
2159
|
+
ctx,
|
|
2160
|
+
(id) => this.quoteIdentifier(id)
|
|
2161
|
+
);
|
|
2162
|
+
}
|
|
2163
|
+
ensureConflictColumns(clause, message) {
|
|
2164
|
+
if (!clause.target.columns.length) throw new Error(message);
|
|
1940
2165
|
}
|
|
1941
2166
|
compileUpdateAssignments(assignments, table, ctx) {
|
|
1942
|
-
return
|
|
1943
|
-
const target = this.compileSetTarget(assignment.column, table);
|
|
1944
|
-
const value = this.compileOperand(assignment.value, ctx);
|
|
1945
|
-
return `${target} = ${value}`;
|
|
1946
|
-
}).join(", ");
|
|
2167
|
+
return this.standardUpdateCompiler.compileAssignments(assignments, table, ctx);
|
|
1947
2168
|
}
|
|
1948
2169
|
compileSetTarget(column, table) {
|
|
1949
2170
|
return this.compileQualifiedColumn(column, table);
|
|
@@ -1956,112 +2177,35 @@ var SqlDialectBase = class extends DialectBase {
|
|
|
1956
2177
|
if (!tableQualifier) return this.quoteIdentifier(column.name);
|
|
1957
2178
|
return `${this.quoteIdentifier(tableQualifier)}.${this.quoteIdentifier(column.name)}`;
|
|
1958
2179
|
}
|
|
1959
|
-
compileDeleteAst(ast, ctx) {
|
|
1960
|
-
const target = this.compileTableReference(ast.from);
|
|
1961
|
-
const usingClause = this.compileDeleteUsingClause(ast, ctx);
|
|
1962
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
1963
|
-
const returning = this.compileReturning(ast.returning, ctx);
|
|
1964
|
-
return `DELETE FROM ${target}${usingClause}${whereClause}${returning}`;
|
|
1965
|
-
}
|
|
1966
2180
|
formatReturningColumns(returning) {
|
|
1967
|
-
return this.returningStrategy.formatReturningColumns(
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
}
|
|
1972
|
-
compileSelectColumns(ast, ctx) {
|
|
1973
|
-
if (!ast.columns || ast.columns.length === 0) return "*";
|
|
1974
|
-
return ast.columns.map((column) => {
|
|
1975
|
-
const expr = this.compileOperand(column, ctx);
|
|
1976
|
-
if (column.alias) {
|
|
1977
|
-
if (column.alias.includes("(")) return column.alias;
|
|
1978
|
-
return `${expr} AS ${this.quoteIdentifier(column.alias)}`;
|
|
1979
|
-
}
|
|
1980
|
-
return expr;
|
|
1981
|
-
}).join(", ");
|
|
2181
|
+
return this.returningStrategy.formatReturningColumns(
|
|
2182
|
+
returning,
|
|
2183
|
+
(id) => this.quoteIdentifier(id)
|
|
2184
|
+
);
|
|
1982
2185
|
}
|
|
1983
|
-
compileFrom(
|
|
1984
|
-
|
|
1985
|
-
if (ast.type === "DerivedTable") return this.compileDerivedTable(ast, ctx);
|
|
1986
|
-
return this.compileTableSource(ast);
|
|
2186
|
+
compileFrom(source, ctx) {
|
|
2187
|
+
return this.sourceCompiler.compileFrom(source, ctx);
|
|
1987
2188
|
}
|
|
1988
2189
|
compileFunctionTable(fn9, ctx) {
|
|
1989
|
-
|
|
1990
|
-
if (ctx) {
|
|
1991
|
-
const renderer = this.tableFunctionStrategy.getRenderer(key);
|
|
1992
|
-
if (renderer) {
|
|
1993
|
-
const compiledArgs = (fn9.args ?? []).map((arg) => this.compileOperand(arg, ctx));
|
|
1994
|
-
return renderer({
|
|
1995
|
-
node: fn9,
|
|
1996
|
-
compiledArgs,
|
|
1997
|
-
compileOperand: (operand) => this.compileOperand(operand, ctx),
|
|
1998
|
-
quoteIdentifier: this.quoteIdentifier.bind(this)
|
|
1999
|
-
});
|
|
2000
|
-
}
|
|
2001
|
-
if (fn9.key) {
|
|
2002
|
-
throw new Error(`Table function "${key}" is not supported by dialect "${this.dialect}".`);
|
|
2003
|
-
}
|
|
2004
|
-
}
|
|
2005
|
-
return FunctionTableFormatter.format(fn9, ctx, {
|
|
2006
|
-
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
2007
|
-
compileOperand: (node, compilerContext) => this.compileOperand(node, compilerContext)
|
|
2008
|
-
});
|
|
2190
|
+
return this.sourceCompiler.compileFunctionTable(fn9, ctx);
|
|
2009
2191
|
}
|
|
2010
2192
|
compileDerivedTable(table, ctx) {
|
|
2011
|
-
|
|
2012
|
-
const subquery = this.compileSelectAst(this.normalizeSelectAst(table.query), ctx).trim().replace(/;$/, "");
|
|
2013
|
-
const columns = table.columnAliases?.length ? ` (${table.columnAliases.map((c) => this.quoteIdentifier(c)).join(", ")})` : "";
|
|
2014
|
-
return `(${subquery}) AS ${this.quoteIdentifier(table.alias)}${columns}`;
|
|
2193
|
+
return this.sourceCompiler.compileDerivedTable(table, ctx);
|
|
2015
2194
|
}
|
|
2016
2195
|
compileTableSource(table) {
|
|
2017
|
-
|
|
2018
|
-
if (table.type === "DerivedTable") return this.compileDerivedTable(table);
|
|
2019
|
-
const base = this.compileTableName(table);
|
|
2020
|
-
return table.alias ? `${base} AS ${this.quoteIdentifier(table.alias)}` : base;
|
|
2196
|
+
return this.sourceCompiler.compileTableSource(table);
|
|
2021
2197
|
}
|
|
2022
2198
|
compileTableName(table) {
|
|
2023
|
-
|
|
2024
|
-
return `${this.quoteIdentifier(table.schema)}.${this.quoteIdentifier(table.name)}`;
|
|
2025
|
-
}
|
|
2026
|
-
return this.quoteIdentifier(table.name);
|
|
2199
|
+
return this.sourceCompiler.compileTableName(table);
|
|
2027
2200
|
}
|
|
2028
2201
|
compileTableReference(table) {
|
|
2029
|
-
|
|
2030
|
-
return table.alias ? `${base} AS ${this.quoteIdentifier(table.alias)}` : base;
|
|
2031
|
-
}
|
|
2032
|
-
compileUpdateFromClause(ast, ctx) {
|
|
2033
|
-
if (!ast.from && (!ast.joins || ast.joins.length === 0)) return "";
|
|
2034
|
-
if (!ast.from) throw new Error("UPDATE with JOINs requires an explicit FROM clause.");
|
|
2035
|
-
const from = this.compileFrom(ast.from, ctx);
|
|
2036
|
-
const joins = JoinCompiler.compileJoins(
|
|
2037
|
-
ast.joins,
|
|
2038
|
-
ctx,
|
|
2039
|
-
this.compileFrom.bind(this),
|
|
2040
|
-
this.compileExpression.bind(this)
|
|
2041
|
-
);
|
|
2042
|
-
return ` FROM ${from}${joins}`;
|
|
2043
|
-
}
|
|
2044
|
-
compileDeleteUsingClause(ast, ctx) {
|
|
2045
|
-
if (!ast.using && (!ast.joins || ast.joins.length === 0)) return "";
|
|
2046
|
-
if (!ast.using) throw new Error("DELETE with JOINs requires a USING clause.");
|
|
2047
|
-
const usingTable = this.compileFrom(ast.using, ctx);
|
|
2048
|
-
const joins = JoinCompiler.compileJoins(
|
|
2049
|
-
ast.joins,
|
|
2050
|
-
ctx,
|
|
2051
|
-
this.compileFrom.bind(this),
|
|
2052
|
-
this.compileExpression.bind(this)
|
|
2053
|
-
);
|
|
2054
|
-
return ` USING ${usingTable}${joins}`;
|
|
2055
|
-
}
|
|
2056
|
-
compileHaving(ast, ctx) {
|
|
2057
|
-
if (!ast.having) return "";
|
|
2058
|
-
return ` HAVING ${this.compileExpression(ast.having, ctx)}`;
|
|
2202
|
+
return this.sourceCompiler.compileTableReference(table);
|
|
2059
2203
|
}
|
|
2060
2204
|
stripTrailingSemicolon(sql) {
|
|
2061
|
-
return
|
|
2205
|
+
return this.sourceCompiler.stripTrailingSemicolon(sql);
|
|
2062
2206
|
}
|
|
2063
2207
|
wrapSetOperand(sql) {
|
|
2064
|
-
return
|
|
2208
|
+
return this.sourceCompiler.wrapSetOperand(sql);
|
|
2065
2209
|
}
|
|
2066
2210
|
renderOrderByNulls(order) {
|
|
2067
2211
|
return order.nulls ? ` NULLS ${order.nulls}` : "";
|
|
@@ -2246,105 +2390,112 @@ var PostgresTableFunctionStrategy = class extends StandardTableFunctionStrategy
|
|
|
2246
2390
|
}
|
|
2247
2391
|
};
|
|
2248
2392
|
|
|
2393
|
+
// src/core/dialect/postgres/procedure-compiler.ts
|
|
2394
|
+
var PostgresProcedureCompiler = class {
|
|
2395
|
+
constructor(services) {
|
|
2396
|
+
this.services = services;
|
|
2397
|
+
}
|
|
2398
|
+
compileProcedureCall(ast) {
|
|
2399
|
+
const ctx = this.services.createCompilerContext();
|
|
2400
|
+
const qualifiedName = ast.ref.schema ? `${this.services.quoteIdentifier(ast.ref.schema)}.${this.services.quoteIdentifier(ast.ref.name)}` : this.services.quoteIdentifier(ast.ref.name);
|
|
2401
|
+
const args = [];
|
|
2402
|
+
for (const param of ast.params) {
|
|
2403
|
+
if (param.direction === "out") continue;
|
|
2404
|
+
if (!param.value) {
|
|
2405
|
+
throw new Error(
|
|
2406
|
+
`Procedure parameter "${param.name}" requires a value for direction "${param.direction}".`
|
|
2407
|
+
);
|
|
2408
|
+
}
|
|
2409
|
+
args.push(this.services.compileOperand(param.value, ctx));
|
|
2410
|
+
}
|
|
2411
|
+
const outNames = ast.params.filter((param) => param.direction === "out" || param.direction === "inout").map((param) => param.name);
|
|
2412
|
+
return {
|
|
2413
|
+
sql: `CALL ${qualifiedName}(${args.join(", ")});`,
|
|
2414
|
+
params: [...ctx.params],
|
|
2415
|
+
outParams: {
|
|
2416
|
+
source: outNames.length ? "firstResultSet" : "none",
|
|
2417
|
+
names: outNames
|
|
2418
|
+
}
|
|
2419
|
+
};
|
|
2420
|
+
}
|
|
2421
|
+
};
|
|
2422
|
+
|
|
2423
|
+
// src/core/dialect/postgres/returning.ts
|
|
2424
|
+
var PostgresReturningStrategy = class extends StandardReturningStrategy {
|
|
2425
|
+
};
|
|
2426
|
+
|
|
2427
|
+
// src/core/dialect/postgres/upsert.ts
|
|
2428
|
+
var PostgresUpsertStrategy = class {
|
|
2429
|
+
compile(ast, ctx, services) {
|
|
2430
|
+
if (!ast.onConflict) return "";
|
|
2431
|
+
const clause = ast.onConflict;
|
|
2432
|
+
const target = clause.target.constraint ? ` ON CONFLICT ON CONSTRAINT ${services.quoteIdentifier(clause.target.constraint)}` : (() => {
|
|
2433
|
+
if (!clause.target.columns.length) {
|
|
2434
|
+
throw new Error("PostgreSQL ON CONFLICT requires conflict columns or a constraint name.");
|
|
2435
|
+
}
|
|
2436
|
+
const columns = clause.target.columns.map((column) => services.quoteIdentifier(column.name)).join(", ");
|
|
2437
|
+
return ` ON CONFLICT (${columns})`;
|
|
2438
|
+
})();
|
|
2439
|
+
if (clause.action.type === "DoNothing") {
|
|
2440
|
+
return `${target} DO NOTHING`;
|
|
2441
|
+
}
|
|
2442
|
+
if (!clause.action.set.length) {
|
|
2443
|
+
throw new Error("PostgreSQL ON CONFLICT DO UPDATE requires at least one assignment.");
|
|
2444
|
+
}
|
|
2445
|
+
const assignments = services.compileUpdateAssignments(clause.action.set, ast.into, ctx);
|
|
2446
|
+
const where = clause.action.where ? ` WHERE ${services.compileExpression(clause.action.where, ctx)}` : "";
|
|
2447
|
+
return `${target} DO UPDATE SET ${assignments}${where}`;
|
|
2448
|
+
}
|
|
2449
|
+
};
|
|
2450
|
+
|
|
2249
2451
|
// src/core/dialect/postgres/index.ts
|
|
2250
2452
|
var PostgresDialect = class extends SqlDialectBase {
|
|
2251
2453
|
dialect = "postgres";
|
|
2252
|
-
|
|
2253
|
-
* Creates a new PostgresDialect instance
|
|
2254
|
-
*/
|
|
2454
|
+
procedureCompiler;
|
|
2255
2455
|
constructor() {
|
|
2256
|
-
super(
|
|
2456
|
+
super({
|
|
2457
|
+
functionStrategy: new PostgresFunctionStrategy(),
|
|
2458
|
+
tableFunctionStrategy: new PostgresTableFunctionStrategy(),
|
|
2459
|
+
returningStrategy: new PostgresReturningStrategy(),
|
|
2460
|
+
upsertStrategy: new PostgresUpsertStrategy(),
|
|
2461
|
+
supportsDmlReturning: true
|
|
2462
|
+
});
|
|
2463
|
+
this.procedureCompiler = new PostgresProcedureCompiler({
|
|
2464
|
+
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
2465
|
+
createCompilerContext: () => this.createCompilerContext(),
|
|
2466
|
+
compileOperand: (node, ctx) => this.compileOperand(node, ctx)
|
|
2467
|
+
});
|
|
2257
2468
|
this.registerExpressionCompiler("BitwiseExpression", (node, ctx) => {
|
|
2258
2469
|
const left2 = this.compileOperand(node.left, ctx);
|
|
2259
2470
|
const right2 = this.compileOperand(node.right, ctx);
|
|
2260
|
-
const
|
|
2261
|
-
return `${left2} ${
|
|
2471
|
+
const operator = node.operator === "^" ? "#" : node.operator;
|
|
2472
|
+
return `${left2} ${operator} ${right2}`;
|
|
2262
2473
|
});
|
|
2263
2474
|
this.registerOperandCompiler("BitwiseExpression", (node, ctx) => {
|
|
2264
2475
|
const left2 = this.compileOperand(node.left, ctx);
|
|
2265
2476
|
const right2 = this.compileOperand(node.right, ctx);
|
|
2266
|
-
const
|
|
2267
|
-
return `(${left2} ${
|
|
2477
|
+
const operator = node.operator === "^" ? "#" : node.operator;
|
|
2478
|
+
return `(${left2} ${operator} ${right2})`;
|
|
2268
2479
|
});
|
|
2269
2480
|
}
|
|
2270
|
-
/**
|
|
2271
|
-
* Quotes an identifier using PostgreSQL double-quote syntax
|
|
2272
|
-
* @param id - Identifier to quote
|
|
2273
|
-
* @returns Quoted identifier
|
|
2274
|
-
*/
|
|
2275
2481
|
quoteIdentifier(id) {
|
|
2276
2482
|
return `"${id}"`;
|
|
2277
2483
|
}
|
|
2278
2484
|
formatPlaceholder(index) {
|
|
2279
2485
|
return `$${index}`;
|
|
2280
2486
|
}
|
|
2281
|
-
/**
|
|
2282
|
-
* Compiles JSON path expression using PostgreSQL syntax
|
|
2283
|
-
* @param node - JSON path node
|
|
2284
|
-
* @returns PostgreSQL JSON path expression
|
|
2285
|
-
*/
|
|
2286
2487
|
compileJsonPath(node) {
|
|
2287
|
-
const
|
|
2288
|
-
return `${
|
|
2289
|
-
}
|
|
2290
|
-
compileReturning(returning, ctx) {
|
|
2291
|
-
void ctx;
|
|
2292
|
-
if (!returning || returning.length === 0) return "";
|
|
2293
|
-
const columns = this.formatReturningColumns(returning);
|
|
2294
|
-
return ` RETURNING ${columns}`;
|
|
2295
|
-
}
|
|
2296
|
-
compileUpsertClause(ast, ctx) {
|
|
2297
|
-
if (!ast.onConflict) return "";
|
|
2298
|
-
const clause = ast.onConflict;
|
|
2299
|
-
const target = clause.target.constraint ? ` ON CONFLICT ON CONSTRAINT ${this.quoteIdentifier(clause.target.constraint)}` : (() => {
|
|
2300
|
-
this.ensureConflictColumns(
|
|
2301
|
-
clause,
|
|
2302
|
-
"PostgreSQL ON CONFLICT requires conflict columns or a constraint name."
|
|
2303
|
-
);
|
|
2304
|
-
const cols = clause.target.columns.map((col2) => this.quoteIdentifier(col2.name)).join(", ");
|
|
2305
|
-
return ` ON CONFLICT (${cols})`;
|
|
2306
|
-
})();
|
|
2307
|
-
if (clause.action.type === "DoNothing") {
|
|
2308
|
-
return `${target} DO NOTHING`;
|
|
2309
|
-
}
|
|
2310
|
-
if (!clause.action.set.length) {
|
|
2311
|
-
throw new Error("PostgreSQL ON CONFLICT DO UPDATE requires at least one assignment.");
|
|
2312
|
-
}
|
|
2313
|
-
const assignments = this.compileUpdateAssignments(clause.action.set, ast.into, ctx);
|
|
2314
|
-
const where = clause.action.where ? ` WHERE ${this.compileExpression(clause.action.where, ctx)}` : "";
|
|
2315
|
-
return `${target} DO UPDATE SET ${assignments}${where}`;
|
|
2316
|
-
}
|
|
2317
|
-
supportsDmlReturningClause() {
|
|
2318
|
-
return true;
|
|
2319
|
-
}
|
|
2320
|
-
compileProcedureCall(ast) {
|
|
2321
|
-
const ctx = this.createCompilerContext();
|
|
2322
|
-
const qualifiedName = ast.ref.schema ? `${this.quoteIdentifier(ast.ref.schema)}.${this.quoteIdentifier(ast.ref.name)}` : this.quoteIdentifier(ast.ref.name);
|
|
2323
|
-
const args = [];
|
|
2324
|
-
for (const param of ast.params) {
|
|
2325
|
-
if (param.direction === "out") continue;
|
|
2326
|
-
if (!param.value) {
|
|
2327
|
-
throw new Error(`Procedure parameter "${param.name}" requires a value for direction "${param.direction}".`);
|
|
2328
|
-
}
|
|
2329
|
-
args.push(this.compileOperand(param.value, ctx));
|
|
2330
|
-
}
|
|
2331
|
-
const outNames = ast.params.filter((param) => param.direction === "out" || param.direction === "inout").map((param) => param.name);
|
|
2332
|
-
const rawSql = `CALL ${qualifiedName}(${args.join(", ")})`;
|
|
2333
|
-
return {
|
|
2334
|
-
sql: `${rawSql};`,
|
|
2335
|
-
params: [...ctx.params],
|
|
2336
|
-
outParams: {
|
|
2337
|
-
source: outNames.length ? "firstResultSet" : "none",
|
|
2338
|
-
names: outNames
|
|
2339
|
-
}
|
|
2340
|
-
};
|
|
2488
|
+
const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
2489
|
+
return `${column}->>'${node.path}'`;
|
|
2341
2490
|
}
|
|
2342
|
-
/**
|
|
2343
|
-
* PostgreSQL requires unqualified column names in SET clause
|
|
2344
|
-
*/
|
|
2491
|
+
/** PostgreSQL requires unqualified column names in SET clauses. */
|
|
2345
2492
|
compileSetTarget(column, _table) {
|
|
2493
|
+
void _table;
|
|
2346
2494
|
return this.quoteIdentifier(column.name);
|
|
2347
2495
|
}
|
|
2496
|
+
compileProcedureCall(ast) {
|
|
2497
|
+
return this.procedureCompiler.compileProcedureCall(ast);
|
|
2498
|
+
}
|
|
2348
2499
|
};
|
|
2349
2500
|
|
|
2350
2501
|
// src/core/dialect/mysql/functions.ts
|
|
@@ -2445,72 +2596,15 @@ var MysqlFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
2445
2596
|
}
|
|
2446
2597
|
};
|
|
2447
2598
|
|
|
2448
|
-
// src/core/dialect/mysql/
|
|
2599
|
+
// src/core/dialect/mysql/procedure-compiler.ts
|
|
2449
2600
|
var sanitizeVariableSuffix = (value) => value.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2450
|
-
var
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
* Creates a new MySqlDialect instance
|
|
2454
|
-
*/
|
|
2455
|
-
constructor() {
|
|
2456
|
-
super(new MysqlFunctionStrategy());
|
|
2457
|
-
this.registerExpressionCompiler(
|
|
2458
|
-
"IsDistinctExpression",
|
|
2459
|
-
(node, ctx) => {
|
|
2460
|
-
const left2 = this.compileOperand(node.left, ctx);
|
|
2461
|
-
const right2 = this.compileOperand(node.right, ctx);
|
|
2462
|
-
const spaceship = `${left2} <=> ${right2}`;
|
|
2463
|
-
if (node.operator === "IS NOT DISTINCT FROM") {
|
|
2464
|
-
return spaceship;
|
|
2465
|
-
}
|
|
2466
|
-
return `NOT (${spaceship})`;
|
|
2467
|
-
}
|
|
2468
|
-
);
|
|
2469
|
-
}
|
|
2470
|
-
/**
|
|
2471
|
-
* Quotes an identifier using MySQL backtick syntax
|
|
2472
|
-
* @param id - Identifier to quote
|
|
2473
|
-
* @returns Quoted identifier
|
|
2474
|
-
*/
|
|
2475
|
-
quoteIdentifier(id) {
|
|
2476
|
-
return `\`${id}\``;
|
|
2477
|
-
}
|
|
2478
|
-
/**
|
|
2479
|
-
* Compiles JSON path expression using MySQL syntax
|
|
2480
|
-
* @param node - JSON path node
|
|
2481
|
-
* @returns MySQL JSON path expression
|
|
2482
|
-
*/
|
|
2483
|
-
compileJsonPath(node) {
|
|
2484
|
-
const col2 = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
2485
|
-
return `${col2}->'${node.path}'`;
|
|
2486
|
-
}
|
|
2487
|
-
compileUpsertClause(ast, ctx) {
|
|
2488
|
-
if (!ast.onConflict) return "";
|
|
2489
|
-
const clause = ast.onConflict;
|
|
2490
|
-
if (clause.action.type === "DoNothing") {
|
|
2491
|
-
const noOpColumn = clause.target.columns[0] ?? ast.columns[0];
|
|
2492
|
-
if (!noOpColumn) {
|
|
2493
|
-
throw new Error("MySQL ON DUPLICATE KEY UPDATE requires at least one target column.");
|
|
2494
|
-
}
|
|
2495
|
-
const col2 = this.quoteIdentifier(noOpColumn.name);
|
|
2496
|
-
return ` ON DUPLICATE KEY UPDATE ${col2} = ${col2}`;
|
|
2497
|
-
}
|
|
2498
|
-
if (clause.action.where) {
|
|
2499
|
-
throw new Error("MySQL ON DUPLICATE KEY UPDATE does not support a WHERE clause.");
|
|
2500
|
-
}
|
|
2501
|
-
if (!clause.action.set.length) {
|
|
2502
|
-
throw new Error("MySQL ON DUPLICATE KEY UPDATE requires at least one assignment.");
|
|
2503
|
-
}
|
|
2504
|
-
const assignments = clause.action.set.map((assignment) => {
|
|
2505
|
-
const target = this.quoteIdentifier(assignment.column.name);
|
|
2506
|
-
const value = this.compileOperand(assignment.value, ctx);
|
|
2507
|
-
return `${target} = ${value}`;
|
|
2508
|
-
}).join(", ");
|
|
2509
|
-
return ` ON DUPLICATE KEY UPDATE ${assignments}`;
|
|
2601
|
+
var MySqlProcedureCompiler = class {
|
|
2602
|
+
constructor(services) {
|
|
2603
|
+
this.services = services;
|
|
2510
2604
|
}
|
|
2511
2605
|
compileProcedureCall(ast) {
|
|
2512
|
-
const ctx = this.createCompilerContext();
|
|
2513
|
-
const qualifiedName = ast.ref.schema ? `${this.quoteIdentifier(ast.ref.schema)}.${this.quoteIdentifier(ast.ref.name)}` : this.quoteIdentifier(ast.ref.name);
|
|
2606
|
+
const ctx = this.services.createCompilerContext();
|
|
2607
|
+
const qualifiedName = ast.ref.schema ? `${this.services.quoteIdentifier(ast.ref.schema)}.${this.services.quoteIdentifier(ast.ref.name)}` : this.services.quoteIdentifier(ast.ref.name);
|
|
2514
2608
|
const prelude = [];
|
|
2515
2609
|
const callArgs = [];
|
|
2516
2610
|
const outVars = [];
|
|
@@ -2521,35 +2615,97 @@ var MySqlDialect = class extends SqlDialectBase {
|
|
|
2521
2615
|
if (!param.value) {
|
|
2522
2616
|
throw new Error(`Procedure parameter "${param.name}" requires a value for direction "in".`);
|
|
2523
2617
|
}
|
|
2524
|
-
callArgs.push(this.compileOperand(param.value, ctx));
|
|
2618
|
+
callArgs.push(this.services.compileOperand(param.value, ctx));
|
|
2525
2619
|
return;
|
|
2526
2620
|
}
|
|
2527
2621
|
if (param.direction === "inout") {
|
|
2528
2622
|
if (!param.value) {
|
|
2529
2623
|
throw new Error(`Procedure parameter "${param.name}" requires a value for direction "inout".`);
|
|
2530
2624
|
}
|
|
2531
|
-
prelude.push(`SET ${variable} = ${this.compileOperand(param.value, ctx)};`);
|
|
2625
|
+
prelude.push(`SET ${variable} = ${this.services.compileOperand(param.value, ctx)};`);
|
|
2532
2626
|
}
|
|
2533
2627
|
callArgs.push(variable);
|
|
2534
2628
|
outVars.push({ variable, name: param.name });
|
|
2535
2629
|
});
|
|
2536
2630
|
const statements = [];
|
|
2537
|
-
if (prelude.length)
|
|
2538
|
-
|
|
2631
|
+
if (prelude.length) statements.push(...prelude);
|
|
2632
|
+
statements.push(`CALL ${qualifiedName}(${callArgs.join(", ")});`);
|
|
2633
|
+
if (outVars.length) {
|
|
2634
|
+
const selectOut = outVars.map(({ variable, name }) => `${variable} AS ${this.services.quoteIdentifier(name)}`).join(", ");
|
|
2635
|
+
statements.push(`SELECT ${selectOut};`);
|
|
2636
|
+
}
|
|
2637
|
+
return {
|
|
2638
|
+
sql: statements.join(" "),
|
|
2639
|
+
params: [...ctx.params],
|
|
2640
|
+
outParams: {
|
|
2641
|
+
source: outVars.length ? "lastResultSet" : "none",
|
|
2642
|
+
names: outVars.map((item) => item.name)
|
|
2643
|
+
}
|
|
2644
|
+
};
|
|
2645
|
+
}
|
|
2646
|
+
};
|
|
2647
|
+
|
|
2648
|
+
// src/core/dialect/mysql/upsert.ts
|
|
2649
|
+
var MySqlUpsertStrategy = class {
|
|
2650
|
+
compile(ast, ctx, services) {
|
|
2651
|
+
if (!ast.onConflict) return "";
|
|
2652
|
+
const clause = ast.onConflict;
|
|
2653
|
+
if (clause.action.type === "DoNothing") {
|
|
2654
|
+
const noOpColumn = clause.target.columns[0] ?? ast.columns[0];
|
|
2655
|
+
if (!noOpColumn) {
|
|
2656
|
+
throw new Error("MySQL ON DUPLICATE KEY UPDATE requires at least one target column.");
|
|
2657
|
+
}
|
|
2658
|
+
const col2 = services.quoteIdentifier(noOpColumn.name);
|
|
2659
|
+
return ` ON DUPLICATE KEY UPDATE ${col2} = ${col2}`;
|
|
2660
|
+
}
|
|
2661
|
+
if (clause.action.where) {
|
|
2662
|
+
throw new Error("MySQL ON DUPLICATE KEY UPDATE does not support a WHERE clause.");
|
|
2539
2663
|
}
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
const selectOut = outVars.map(({ variable, name }) => `${variable} AS ${this.quoteIdentifier(name)}`).join(", ");
|
|
2543
|
-
statements.push(`SELECT ${selectOut};`);
|
|
2664
|
+
if (!clause.action.set.length) {
|
|
2665
|
+
throw new Error("MySQL ON DUPLICATE KEY UPDATE requires at least one assignment.");
|
|
2544
2666
|
}
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2667
|
+
const assignments = clause.action.set.map((assignment) => {
|
|
2668
|
+
const target = services.quoteIdentifier(assignment.column.name);
|
|
2669
|
+
const value = services.compileOperand(assignment.value, ctx);
|
|
2670
|
+
return `${target} = ${value}`;
|
|
2671
|
+
}).join(", ");
|
|
2672
|
+
return ` ON DUPLICATE KEY UPDATE ${assignments}`;
|
|
2673
|
+
}
|
|
2674
|
+
};
|
|
2675
|
+
|
|
2676
|
+
// src/core/dialect/mysql/index.ts
|
|
2677
|
+
var MySqlDialect = class extends SqlDialectBase {
|
|
2678
|
+
dialect = "mysql";
|
|
2679
|
+
procedureCompiler;
|
|
2680
|
+
constructor() {
|
|
2681
|
+
super({
|
|
2682
|
+
functionStrategy: new MysqlFunctionStrategy(),
|
|
2683
|
+
upsertStrategy: new MySqlUpsertStrategy()
|
|
2684
|
+
});
|
|
2685
|
+
this.procedureCompiler = new MySqlProcedureCompiler({
|
|
2686
|
+
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
2687
|
+
createCompilerContext: () => this.createCompilerContext(),
|
|
2688
|
+
compileOperand: (node, ctx) => this.compileOperand(node, ctx)
|
|
2689
|
+
});
|
|
2690
|
+
this.registerExpressionCompiler(
|
|
2691
|
+
"IsDistinctExpression",
|
|
2692
|
+
(node, ctx) => {
|
|
2693
|
+
const left2 = this.compileOperand(node.left, ctx);
|
|
2694
|
+
const right2 = this.compileOperand(node.right, ctx);
|
|
2695
|
+
const spaceship = `${left2} <=> ${right2}`;
|
|
2696
|
+
return node.operator === "IS NOT DISTINCT FROM" ? spaceship : `NOT (${spaceship})`;
|
|
2551
2697
|
}
|
|
2552
|
-
|
|
2698
|
+
);
|
|
2699
|
+
}
|
|
2700
|
+
quoteIdentifier(id) {
|
|
2701
|
+
return `\`${id}\``;
|
|
2702
|
+
}
|
|
2703
|
+
compileJsonPath(node) {
|
|
2704
|
+
const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
2705
|
+
return `${column}->'${node.path}'`;
|
|
2706
|
+
}
|
|
2707
|
+
compileProcedureCall(ast) {
|
|
2708
|
+
return this.procedureCompiler.compileProcedureCall(ast);
|
|
2553
2709
|
}
|
|
2554
2710
|
};
|
|
2555
2711
|
|
|
@@ -2690,14 +2846,56 @@ var SqliteFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
2690
2846
|
}
|
|
2691
2847
|
};
|
|
2692
2848
|
|
|
2849
|
+
// src/core/dialect/sqlite/returning.ts
|
|
2850
|
+
var SqliteReturningStrategy = class {
|
|
2851
|
+
compileReturning(returning, _ctx, quoteIdentifier) {
|
|
2852
|
+
void _ctx;
|
|
2853
|
+
if (!returning || returning.length === 0) return "";
|
|
2854
|
+
return ` RETURNING ${this.formatReturningColumns(returning, quoteIdentifier)}`;
|
|
2855
|
+
}
|
|
2856
|
+
formatReturningColumns(returning, quoteIdentifier) {
|
|
2857
|
+
return returning.map((column) => {
|
|
2858
|
+
const alias = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : "";
|
|
2859
|
+
return `${quoteIdentifier(column.name)}${alias}`;
|
|
2860
|
+
}).join(", ");
|
|
2861
|
+
}
|
|
2862
|
+
};
|
|
2863
|
+
|
|
2864
|
+
// src/core/dialect/sqlite/upsert.ts
|
|
2865
|
+
var SqliteUpsertStrategy = class {
|
|
2866
|
+
compile(ast, ctx, services) {
|
|
2867
|
+
if (!ast.onConflict) return "";
|
|
2868
|
+
const clause = ast.onConflict;
|
|
2869
|
+
if (clause.target.constraint) {
|
|
2870
|
+
throw new Error("SQLite ON CONFLICT does not support named constraints.");
|
|
2871
|
+
}
|
|
2872
|
+
if (!clause.target.columns.length) {
|
|
2873
|
+
throw new Error("SQLite ON CONFLICT requires conflict columns.");
|
|
2874
|
+
}
|
|
2875
|
+
const columns = clause.target.columns.map((column) => services.quoteIdentifier(column.name)).join(", ");
|
|
2876
|
+
const target = ` ON CONFLICT (${columns})`;
|
|
2877
|
+
if (clause.action.type === "DoNothing") {
|
|
2878
|
+
return `${target} DO NOTHING`;
|
|
2879
|
+
}
|
|
2880
|
+
if (!clause.action.set.length) {
|
|
2881
|
+
throw new Error("SQLite ON CONFLICT DO UPDATE requires at least one assignment.");
|
|
2882
|
+
}
|
|
2883
|
+
const assignments = services.compileUpdateAssignments(clause.action.set, ast.into, ctx);
|
|
2884
|
+
const where = clause.action.where ? ` WHERE ${services.compileExpression(clause.action.where, ctx)}` : "";
|
|
2885
|
+
return `${target} DO UPDATE SET ${assignments}${where}`;
|
|
2886
|
+
}
|
|
2887
|
+
};
|
|
2888
|
+
|
|
2693
2889
|
// src/core/dialect/sqlite/index.ts
|
|
2694
2890
|
var SqliteDialect = class extends SqlDialectBase {
|
|
2695
2891
|
dialect = "sqlite";
|
|
2696
|
-
/**
|
|
2697
|
-
* Creates a new SqliteDialect instance
|
|
2698
|
-
*/
|
|
2699
2892
|
constructor() {
|
|
2700
|
-
super(
|
|
2893
|
+
super({
|
|
2894
|
+
functionStrategy: new SqliteFunctionStrategy(),
|
|
2895
|
+
returningStrategy: new SqliteReturningStrategy(),
|
|
2896
|
+
upsertStrategy: new SqliteUpsertStrategy(),
|
|
2897
|
+
supportsDmlReturning: true
|
|
2898
|
+
});
|
|
2701
2899
|
this.registerExpressionCompiler("BitwiseExpression", (node, ctx) => {
|
|
2702
2900
|
const left2 = this.compileOperand(node.left, ctx);
|
|
2703
2901
|
const right2 = this.compileOperand(node.right, ctx);
|
|
@@ -2715,61 +2913,17 @@ var SqliteDialect = class extends SqlDialectBase {
|
|
|
2715
2913
|
return `(${left2} ${node.operator} ${right2})`;
|
|
2716
2914
|
});
|
|
2717
2915
|
}
|
|
2718
|
-
/**
|
|
2719
|
-
* Quotes an identifier using SQLite double-quote syntax
|
|
2720
|
-
* @param id - Identifier to quote
|
|
2721
|
-
* @returns Quoted identifier
|
|
2722
|
-
*/
|
|
2723
2916
|
quoteIdentifier(id) {
|
|
2724
2917
|
return `"${id}"`;
|
|
2725
2918
|
}
|
|
2726
|
-
/**
|
|
2727
|
-
* Compiles JSON path expression using SQLite syntax
|
|
2728
|
-
* @param node - JSON path node
|
|
2729
|
-
* @returns SQLite JSON path expression
|
|
2730
|
-
*/
|
|
2731
2919
|
compileJsonPath(node) {
|
|
2732
|
-
const
|
|
2733
|
-
return `json_extract(${
|
|
2920
|
+
const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
2921
|
+
return `json_extract(${column}, '${node.path}')`;
|
|
2734
2922
|
}
|
|
2735
2923
|
compileQualifiedColumn(column, _table) {
|
|
2736
2924
|
void _table;
|
|
2737
2925
|
return this.quoteIdentifier(column.name);
|
|
2738
2926
|
}
|
|
2739
|
-
compileReturning(returning, ctx) {
|
|
2740
|
-
void ctx;
|
|
2741
|
-
if (!returning || returning.length === 0) return "";
|
|
2742
|
-
const columns = this.formatReturningColumns(returning);
|
|
2743
|
-
return ` RETURNING ${columns}`;
|
|
2744
|
-
}
|
|
2745
|
-
formatReturningColumns(returning) {
|
|
2746
|
-
return returning.map((column) => {
|
|
2747
|
-
const alias = column.alias ? ` AS ${this.quoteIdentifier(column.alias)}` : "";
|
|
2748
|
-
return `${this.quoteIdentifier(column.name)}${alias}`;
|
|
2749
|
-
}).join(", ");
|
|
2750
|
-
}
|
|
2751
|
-
compileUpsertClause(ast, ctx) {
|
|
2752
|
-
if (!ast.onConflict) return "";
|
|
2753
|
-
const clause = ast.onConflict;
|
|
2754
|
-
if (clause.target.constraint) {
|
|
2755
|
-
throw new Error("SQLite ON CONFLICT does not support named constraints.");
|
|
2756
|
-
}
|
|
2757
|
-
this.ensureConflictColumns(clause, "SQLite ON CONFLICT requires conflict columns.");
|
|
2758
|
-
const cols = clause.target.columns.map((col2) => this.quoteIdentifier(col2.name)).join(", ");
|
|
2759
|
-
const target = ` ON CONFLICT (${cols})`;
|
|
2760
|
-
if (clause.action.type === "DoNothing") {
|
|
2761
|
-
return `${target} DO NOTHING`;
|
|
2762
|
-
}
|
|
2763
|
-
if (!clause.action.set.length) {
|
|
2764
|
-
throw new Error("SQLite ON CONFLICT DO UPDATE requires at least one assignment.");
|
|
2765
|
-
}
|
|
2766
|
-
const assignments = this.compileUpdateAssignments(clause.action.set, ast.into, ctx);
|
|
2767
|
-
const where = clause.action.where ? ` WHERE ${this.compileExpression(clause.action.where, ctx)}` : "";
|
|
2768
|
-
return `${target} DO UPDATE SET ${assignments}${where}`;
|
|
2769
|
-
}
|
|
2770
|
-
supportsDmlReturningClause() {
|
|
2771
|
-
return true;
|
|
2772
|
-
}
|
|
2773
2927
|
};
|
|
2774
2928
|
|
|
2775
2929
|
// src/core/dialect/mssql/functions.ts
|
|
@@ -2896,202 +3050,107 @@ var MssqlFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
2896
3050
|
}
|
|
2897
3051
|
};
|
|
2898
3052
|
|
|
2899
|
-
// src/core/dialect/mssql/
|
|
2900
|
-
var
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
/**
|
|
2905
|
-
* Creates a new SqlServerDialect instance
|
|
2906
|
-
*/
|
|
2907
|
-
constructor() {
|
|
2908
|
-
super(new MssqlFunctionStrategy());
|
|
2909
|
-
}
|
|
2910
|
-
/**
|
|
2911
|
-
* Quotes an identifier using SQL Server bracket syntax
|
|
2912
|
-
* @param id - Identifier to quote
|
|
2913
|
-
* @returns Quoted identifier
|
|
2914
|
-
*/
|
|
2915
|
-
quoteIdentifier(id) {
|
|
2916
|
-
return `[${id}]`;
|
|
2917
|
-
}
|
|
2918
|
-
/**
|
|
2919
|
-
* Compiles JSON path expression using SQL Server syntax
|
|
2920
|
-
* @param node - JSON path node
|
|
2921
|
-
* @returns SQL Server JSON path expression
|
|
2922
|
-
*/
|
|
2923
|
-
compileJsonPath(node) {
|
|
2924
|
-
const col2 = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
2925
|
-
return `JSON_VALUE(${col2}, '${node.path}')`;
|
|
3053
|
+
// src/core/dialect/mssql/output.ts
|
|
3054
|
+
var MssqlOutputStrategy = class {
|
|
3055
|
+
compileReturning(returning, _ctx, quoteIdentifier) {
|
|
3056
|
+
void _ctx;
|
|
3057
|
+
return this.compileOutput(returning, "inserted", quoteIdentifier);
|
|
2926
3058
|
}
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
return
|
|
3059
|
+
compileOutput(returning, prefix, quoteIdentifier) {
|
|
3060
|
+
if (!returning || returning.length === 0) return "";
|
|
3061
|
+
const columns = returning.map((column) => {
|
|
3062
|
+
const alias = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : "";
|
|
3063
|
+
return `${prefix}.${quoteIdentifier(column.name)}${alias}`;
|
|
3064
|
+
}).join(", ");
|
|
3065
|
+
return ` OUTPUT ${columns}`;
|
|
2934
3066
|
}
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
*/
|
|
2941
|
-
compileSelectAst(ast, ctx) {
|
|
2942
|
-
const hasSetOps = !!(ast.setOps && ast.setOps.length);
|
|
2943
|
-
const ctes = this.compileCtes(ast, ctx);
|
|
2944
|
-
const baseAst = hasSetOps ? { ...ast, setOps: void 0, orderBy: void 0, limit: void 0, offset: void 0 } : ast;
|
|
2945
|
-
const baseSelect = this.compileSelectCoreForMssql(baseAst, ctx);
|
|
2946
|
-
if (!hasSetOps) {
|
|
2947
|
-
return `${ctes}${baseSelect}`;
|
|
2948
|
-
}
|
|
2949
|
-
const compound = ast.setOps.map((op) => `${op.operator} ${this.wrapSetOperand(this.compileSelectAst(op.query, ctx))}`).join(" ");
|
|
2950
|
-
const orderBy = this.compileOrderBy(ast, ctx);
|
|
2951
|
-
const pagination = this.compilePagination(ast, orderBy);
|
|
2952
|
-
const combined = `${this.wrapSetOperand(baseSelect)} ${compound}`;
|
|
2953
|
-
const tail = pagination || orderBy;
|
|
2954
|
-
return `${ctes}${combined}${tail}`;
|
|
3067
|
+
formatReturningColumns(returning, quoteIdentifier) {
|
|
3068
|
+
return returning.map((column) => {
|
|
3069
|
+
const alias = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : "";
|
|
3070
|
+
return `${quoteIdentifier(column.name)}${alias}`;
|
|
3071
|
+
}).join(", ");
|
|
2955
3072
|
}
|
|
2956
|
-
|
|
3073
|
+
};
|
|
3074
|
+
|
|
3075
|
+
// src/core/dialect/mssql/delete-compiler.ts
|
|
3076
|
+
var MssqlDeleteCompiler = class {
|
|
3077
|
+
constructor(services, sources) {
|
|
3078
|
+
this.services = services;
|
|
3079
|
+
this.sources = sources;
|
|
3080
|
+
}
|
|
3081
|
+
output = new MssqlOutputStrategy();
|
|
3082
|
+
compile(ast, ctx) {
|
|
2957
3083
|
if (ast.using) {
|
|
2958
3084
|
throw new Error("DELETE ... USING is not supported in the MSSQL dialect; use join() instead.");
|
|
2959
3085
|
}
|
|
2960
|
-
if (ast.from.type !== "Table") {
|
|
2961
|
-
throw new Error("DELETE only supports base tables in the MSSQL dialect.");
|
|
2962
|
-
}
|
|
2963
3086
|
const alias = ast.from.alias ?? ast.from.name;
|
|
2964
|
-
const target = this.compileTableReference(ast.from);
|
|
3087
|
+
const target = this.sources.compileTableReference(ast.from);
|
|
2965
3088
|
const joins = JoinCompiler.compileJoins(
|
|
2966
3089
|
ast.joins,
|
|
2967
3090
|
ctx,
|
|
2968
|
-
this.compileFrom
|
|
2969
|
-
this.compileExpression
|
|
3091
|
+
(source, compilerContext) => this.sources.compileFrom(source, compilerContext),
|
|
3092
|
+
(expression, compilerContext) => this.services.compileExpression(expression, compilerContext)
|
|
2970
3093
|
);
|
|
2971
|
-
const
|
|
2972
|
-
const returning = this.
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
const target = this.compileTableReference(ast.table);
|
|
2977
|
-
const assignments = this.compileUpdateAssignments(ast.set, ast.table, ctx);
|
|
2978
|
-
const output = this.compileReturning(ast.returning, ctx);
|
|
2979
|
-
const fromClause = ast.from ? ` FROM ${this.compileFrom(ast.from, ctx)}` : "";
|
|
2980
|
-
const joins = ast.joins ? ast.joins.map((j) => {
|
|
2981
|
-
const table = this.compileFrom(j.table, ctx);
|
|
2982
|
-
const cond = this.compileExpression(j.condition, ctx);
|
|
2983
|
-
return ` ${j.kind} JOIN ${table} ON ${cond}`;
|
|
2984
|
-
}).join("") : "";
|
|
2985
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
2986
|
-
return `UPDATE ${target} SET ${assignments}${output}${fromClause}${joins}${whereClause}`;
|
|
2987
|
-
}
|
|
2988
|
-
compileSelectCoreForMssql(ast, ctx) {
|
|
2989
|
-
const columns = ast.columns.map((c) => {
|
|
2990
|
-
const expr = c.type === "Column" ? `${this.quoteIdentifier(c.table)}.${this.quoteIdentifier(c.name)}` : this.compileOperand(c, ctx);
|
|
2991
|
-
if (c.alias) {
|
|
2992
|
-
if (c.alias.includes("(")) return c.alias;
|
|
2993
|
-
return `${expr} AS ${this.quoteIdentifier(c.alias)}`;
|
|
2994
|
-
}
|
|
2995
|
-
return expr;
|
|
2996
|
-
}).join(", ");
|
|
2997
|
-
const distinct = ast.distinct ? "DISTINCT " : "";
|
|
2998
|
-
const from = this.compileFrom(ast.from, ctx);
|
|
2999
|
-
const joins = ast.joins.map((j) => {
|
|
3000
|
-
const table = this.compileFrom(j.table, ctx);
|
|
3001
|
-
const cond = this.compileExpression(j.condition, ctx);
|
|
3002
|
-
return `${j.kind} JOIN ${table} ON ${cond}`;
|
|
3003
|
-
}).join(" ");
|
|
3004
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3005
|
-
const groupBy = ast.groupBy && ast.groupBy.length > 0 ? " GROUP BY " + ast.groupBy.map((term) => this.compileOrderingTerm(term, ctx)).join(", ") : "";
|
|
3006
|
-
const having = ast.having ? ` HAVING ${this.compileExpression(ast.having, ctx)}` : "";
|
|
3007
|
-
const orderBy = this.compileOrderBy(ast, ctx);
|
|
3008
|
-
const pagination = this.compilePagination(ast, orderBy);
|
|
3009
|
-
if (pagination) {
|
|
3010
|
-
return `SELECT ${distinct}${columns} FROM ${from}${joins ? " " + joins : ""}${whereClause}${groupBy}${having}${pagination}`;
|
|
3011
|
-
}
|
|
3012
|
-
return `SELECT ${distinct}${columns} FROM ${from}${joins ? " " + joins : ""}${whereClause}${groupBy}${having}${orderBy}`;
|
|
3013
|
-
}
|
|
3014
|
-
compileOrderBy(ast, ctx) {
|
|
3015
|
-
return OrderByCompiler.compileOrderBy(
|
|
3016
|
-
ast,
|
|
3017
|
-
(term) => this.compileOrderingTerm(term, ctx),
|
|
3018
|
-
this.renderOrderByNulls.bind(this),
|
|
3019
|
-
this.renderOrderByCollation.bind(this)
|
|
3094
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
3095
|
+
const returning = this.output.compileOutput(
|
|
3096
|
+
ast.returning,
|
|
3097
|
+
"deleted",
|
|
3098
|
+
(id) => this.services.quoteIdentifier(id)
|
|
3020
3099
|
);
|
|
3100
|
+
return `DELETE ${this.services.quoteIdentifier(alias)}${returning} FROM ${target}${joins}${where}`;
|
|
3021
3101
|
}
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
orderClause = ast.distinct && ast.distinct.length > 0 ? " ORDER BY 1" : " ORDER BY (SELECT NULL)";
|
|
3030
|
-
}
|
|
3031
|
-
let pagination = `${orderClause} OFFSET ${off} ROWS`;
|
|
3032
|
-
if (hasLimit) {
|
|
3033
|
-
pagination += ` FETCH NEXT ${ast.limit} ROWS ONLY`;
|
|
3034
|
-
}
|
|
3035
|
-
return pagination;
|
|
3036
|
-
}
|
|
3037
|
-
supportsDmlReturningClause() {
|
|
3038
|
-
return true;
|
|
3039
|
-
}
|
|
3040
|
-
compileReturning(returning, _ctx) {
|
|
3041
|
-
void _ctx;
|
|
3042
|
-
return this.compileOutputClause(returning, "inserted");
|
|
3043
|
-
}
|
|
3044
|
-
compileOutputClause(returning, prefix) {
|
|
3045
|
-
if (!returning || returning.length === 0) return "";
|
|
3046
|
-
const columns = returning.map((column) => {
|
|
3047
|
-
const colName = this.quoteIdentifier(column.name);
|
|
3048
|
-
const alias = column.alias ? ` AS ${this.quoteIdentifier(column.alias)}` : "";
|
|
3049
|
-
return `${prefix}.${colName}${alias}`;
|
|
3050
|
-
}).join(", ");
|
|
3051
|
-
return ` OUTPUT ${columns}`;
|
|
3102
|
+
};
|
|
3103
|
+
|
|
3104
|
+
// src/core/dialect/mssql/insert-compiler.ts
|
|
3105
|
+
var MssqlInsertCompiler = class {
|
|
3106
|
+
constructor(services, sources) {
|
|
3107
|
+
this.services = services;
|
|
3108
|
+
this.sources = sources;
|
|
3052
3109
|
}
|
|
3053
|
-
|
|
3110
|
+
compile(ast, ctx) {
|
|
3054
3111
|
if (!ast.columns.length) {
|
|
3055
3112
|
throw new Error("INSERT queries must specify columns.");
|
|
3056
3113
|
}
|
|
3057
|
-
if (ast.onConflict)
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
const
|
|
3061
|
-
const
|
|
3062
|
-
|
|
3063
|
-
const source = this.compileInsertValues(ast, ctx);
|
|
3064
|
-
return `INSERT INTO ${table} (${columnList})${output} ${source}`;
|
|
3114
|
+
if (ast.onConflict) return this.compileMerge(ast, ctx);
|
|
3115
|
+
const table = this.sources.compileTableName(ast.into);
|
|
3116
|
+
const columns = ast.columns.map((column) => this.services.quoteIdentifier(column.name)).join(", ");
|
|
3117
|
+
const output = this.services.compileReturning(ast.returning, ctx);
|
|
3118
|
+
const source = this.compileInsertSource(ast, ctx);
|
|
3119
|
+
return `INSERT INTO ${table} (${columns})${output} ${source}`;
|
|
3065
3120
|
}
|
|
3066
|
-
|
|
3121
|
+
compileMerge(ast, ctx) {
|
|
3067
3122
|
const clause = ast.onConflict;
|
|
3068
3123
|
if (clause.target.constraint) {
|
|
3069
3124
|
throw new Error("MSSQL MERGE does not support conflict target by constraint name.");
|
|
3070
3125
|
}
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
const
|
|
3075
|
-
const
|
|
3126
|
+
if (!clause.target.columns.length) {
|
|
3127
|
+
throw new Error("MSSQL MERGE requires conflict columns for the ON clause.");
|
|
3128
|
+
}
|
|
3129
|
+
const table = this.sources.compileTableName(ast.into);
|
|
3130
|
+
const targetRef = this.services.quoteIdentifier(ast.into.alias ?? ast.into.name);
|
|
3131
|
+
const sourceAlias = this.services.quoteIdentifier("src");
|
|
3132
|
+
const sourceColumns = ast.columns.map((column) => this.services.quoteIdentifier(column.name)).join(", ");
|
|
3076
3133
|
const usingSource = this.compileMergeUsingSource(ast, ctx);
|
|
3077
|
-
const onClause = clause.target.columns.map(
|
|
3134
|
+
const onClause = clause.target.columns.map(
|
|
3135
|
+
(column) => `${targetRef}.${this.services.quoteIdentifier(column.name)} = ${sourceAlias}.${this.services.quoteIdentifier(column.name)}`
|
|
3136
|
+
).join(" AND ");
|
|
3078
3137
|
const branches = [];
|
|
3079
3138
|
if (clause.action.type === "DoUpdate") {
|
|
3080
3139
|
if (!clause.action.set.length) {
|
|
3081
3140
|
throw new Error("MSSQL MERGE WHEN MATCHED UPDATE requires at least one assignment.");
|
|
3082
3141
|
}
|
|
3083
3142
|
const assignments = clause.action.set.map((assignment) => {
|
|
3084
|
-
const target = `${targetRef}.${this.quoteIdentifier(assignment.column.name)}`;
|
|
3085
|
-
const value = this.compileOperand(assignment.value, ctx);
|
|
3143
|
+
const target = `${targetRef}.${this.services.quoteIdentifier(assignment.column.name)}`;
|
|
3144
|
+
const value = this.services.compileOperand(assignment.value, ctx);
|
|
3086
3145
|
return `${target} = ${value}`;
|
|
3087
3146
|
}).join(", ");
|
|
3088
|
-
const guard = clause.action.where ? ` AND ${this.compileExpression(clause.action.where, ctx)}` : "";
|
|
3147
|
+
const guard = clause.action.where ? ` AND ${this.services.compileExpression(clause.action.where, ctx)}` : "";
|
|
3089
3148
|
branches.push(`WHEN MATCHED${guard} THEN UPDATE SET ${assignments}`);
|
|
3090
3149
|
}
|
|
3091
|
-
const insertColumns = ast.columns.map((column) => this.quoteIdentifier(column.name)).join(", ");
|
|
3092
|
-
const insertValues = ast.columns.map((column) => `${sourceAlias}.${this.quoteIdentifier(column.name)}`).join(", ");
|
|
3150
|
+
const insertColumns = ast.columns.map((column) => this.services.quoteIdentifier(column.name)).join(", ");
|
|
3151
|
+
const insertValues = ast.columns.map((column) => `${sourceAlias}.${this.services.quoteIdentifier(column.name)}`).join(", ");
|
|
3093
3152
|
branches.push(`WHEN NOT MATCHED THEN INSERT (${insertColumns}) VALUES (${insertValues})`);
|
|
3094
|
-
const output = this.compileReturning(ast.returning, ctx);
|
|
3153
|
+
const output = this.services.compileReturning(ast.returning, ctx);
|
|
3095
3154
|
return `MERGE INTO ${table} USING ${usingSource} AS ${sourceAlias} (${sourceColumns}) ON ${onClause} ${branches.join(" ")}${output}`;
|
|
3096
3155
|
}
|
|
3097
3156
|
compileMergeUsingSource(ast, ctx) {
|
|
@@ -3099,38 +3158,146 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
3099
3158
|
if (!ast.source.rows.length) {
|
|
3100
3159
|
throw new Error("INSERT ... VALUES requires at least one row.");
|
|
3101
3160
|
}
|
|
3102
|
-
const rows = ast.source.rows.map((row) => `(${row.map((value) => this.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
3161
|
+
const rows = ast.source.rows.map((row) => `(${row.map((value) => this.services.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
3103
3162
|
return `(VALUES ${rows})`;
|
|
3104
3163
|
}
|
|
3105
|
-
const normalized = this.normalizeSelectAst(ast.source.query);
|
|
3106
|
-
const selectSql = this.
|
|
3164
|
+
const normalized = this.services.normalizeSelectAst(ast.source.query);
|
|
3165
|
+
const selectSql = this.sources.stripTrailingSemicolon(
|
|
3166
|
+
this.services.compileSelectAst(normalized, ctx)
|
|
3167
|
+
);
|
|
3107
3168
|
return `(${selectSql})`;
|
|
3108
3169
|
}
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
if (!source.rows.length) {
|
|
3170
|
+
compileInsertSource(ast, ctx) {
|
|
3171
|
+
if (ast.source.type === "InsertValues") {
|
|
3172
|
+
if (!ast.source.rows.length) {
|
|
3113
3173
|
throw new Error("INSERT ... VALUES requires at least one row.");
|
|
3114
3174
|
}
|
|
3115
|
-
const values = source.rows.map((row) => `(${row.map((value) => this.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
3175
|
+
const values = ast.source.rows.map((row) => `(${row.map((value) => this.services.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
3116
3176
|
return `VALUES ${values}`;
|
|
3117
3177
|
}
|
|
3118
|
-
const normalized = this.normalizeSelectAst(source.query);
|
|
3119
|
-
return this.compileSelectAst(normalized, ctx).trim();
|
|
3178
|
+
const normalized = this.services.normalizeSelectAst(ast.source.query);
|
|
3179
|
+
return this.services.compileSelectAst(normalized, ctx).trim();
|
|
3180
|
+
}
|
|
3181
|
+
};
|
|
3182
|
+
|
|
3183
|
+
// src/core/dialect/mssql/select-compiler.ts
|
|
3184
|
+
var MssqlSelectCompiler = class {
|
|
3185
|
+
constructor(services, sources) {
|
|
3186
|
+
this.services = services;
|
|
3187
|
+
this.sources = sources;
|
|
3188
|
+
}
|
|
3189
|
+
compile(ast, ctx) {
|
|
3190
|
+
const hasSetOps = !!(ast.setOps && ast.setOps.length);
|
|
3191
|
+
const ctes = this.compileCtes(ast, ctx);
|
|
3192
|
+
const baseAst = hasSetOps ? { ...ast, setOps: void 0, orderBy: void 0, limit: void 0, offset: void 0 } : ast;
|
|
3193
|
+
const baseSelect = this.compileCore(baseAst, ctx);
|
|
3194
|
+
if (!hasSetOps) return `${ctes}${baseSelect}`;
|
|
3195
|
+
const compound = ast.setOps.map((op) => `${op.operator} ${this.sources.wrapSetOperand(this.services.compileSelectAst(op.query, ctx))}`).join(" ");
|
|
3196
|
+
const orderBy = this.compileOrderBy(ast, ctx);
|
|
3197
|
+
const pagination = this.compilePagination(ast, orderBy);
|
|
3198
|
+
const combined = `${this.sources.wrapSetOperand(baseSelect)} ${compound}`;
|
|
3199
|
+
return `${ctes}${combined}${pagination || orderBy}`;
|
|
3200
|
+
}
|
|
3201
|
+
compileCore(ast, ctx) {
|
|
3202
|
+
const columns = ast.columns.map((column) => {
|
|
3203
|
+
const expr = column.type === "Column" ? `${this.services.quoteIdentifier(column.table)}.${this.services.quoteIdentifier(column.name)}` : this.services.compileOperand(column, ctx);
|
|
3204
|
+
if (!column.alias) return expr;
|
|
3205
|
+
if (column.alias.includes("(")) return column.alias;
|
|
3206
|
+
return `${expr} AS ${this.services.quoteIdentifier(column.alias)}`;
|
|
3207
|
+
}).join(", ");
|
|
3208
|
+
const distinct = ast.distinct ? "DISTINCT " : "";
|
|
3209
|
+
const from = this.sources.compileFrom(ast.from, ctx);
|
|
3210
|
+
const joins = ast.joins.map((join) => {
|
|
3211
|
+
const table = this.sources.compileFrom(join.table, ctx);
|
|
3212
|
+
const condition = this.services.compileExpression(join.condition, ctx);
|
|
3213
|
+
return `${join.kind} JOIN ${table} ON ${condition}`;
|
|
3214
|
+
}).join(" ");
|
|
3215
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
3216
|
+
const groupBy = ast.groupBy && ast.groupBy.length > 0 ? ` GROUP BY ${ast.groupBy.map((term) => this.services.compileOrderingTerm(term, ctx)).join(", ")}` : "";
|
|
3217
|
+
const having = ast.having ? ` HAVING ${this.services.compileExpression(ast.having, ctx)}` : "";
|
|
3218
|
+
const orderBy = this.compileOrderBy(ast, ctx);
|
|
3219
|
+
const pagination = this.compilePagination(ast, orderBy);
|
|
3220
|
+
if (pagination) {
|
|
3221
|
+
return `SELECT ${distinct}${columns} FROM ${from}${joins ? ` ${joins}` : ""}${where}${groupBy}${having}${pagination}`;
|
|
3222
|
+
}
|
|
3223
|
+
return `SELECT ${distinct}${columns} FROM ${from}${joins ? ` ${joins}` : ""}${where}${groupBy}${having}${orderBy}`;
|
|
3224
|
+
}
|
|
3225
|
+
compileOrderBy(ast, ctx) {
|
|
3226
|
+
return OrderByCompiler.compileOrderBy(
|
|
3227
|
+
ast,
|
|
3228
|
+
(term) => this.services.compileOrderingTerm(term, ctx),
|
|
3229
|
+
(order) => this.services.renderOrderByNulls(order),
|
|
3230
|
+
(order) => this.services.renderOrderByCollation(order)
|
|
3231
|
+
);
|
|
3232
|
+
}
|
|
3233
|
+
compilePagination(ast, orderBy) {
|
|
3234
|
+
const hasLimit = ast.limit !== void 0;
|
|
3235
|
+
const hasOffset = ast.offset !== void 0;
|
|
3236
|
+
if (!hasLimit && !hasOffset) return "";
|
|
3237
|
+
const offset = ast.offset ?? 0;
|
|
3238
|
+
let orderClause = orderBy;
|
|
3239
|
+
if (!orderClause) {
|
|
3240
|
+
orderClause = ast.distinct && ast.distinct.length > 0 ? " ORDER BY 1" : " ORDER BY (SELECT NULL)";
|
|
3241
|
+
}
|
|
3242
|
+
let pagination = `${orderClause} OFFSET ${offset} ROWS`;
|
|
3243
|
+
if (hasLimit) pagination += ` FETCH NEXT ${ast.limit} ROWS ONLY`;
|
|
3244
|
+
return pagination;
|
|
3120
3245
|
}
|
|
3121
3246
|
compileCtes(ast, ctx) {
|
|
3122
3247
|
if (!ast.ctes || ast.ctes.length === 0) return "";
|
|
3123
|
-
const
|
|
3124
|
-
const name = this.quoteIdentifier(cte.name);
|
|
3125
|
-
const
|
|
3126
|
-
const query = this.
|
|
3127
|
-
|
|
3248
|
+
const definitions = ast.ctes.map((cte) => {
|
|
3249
|
+
const name = this.services.quoteIdentifier(cte.name);
|
|
3250
|
+
const columns = cte.columns ? `(${cte.columns.map((column) => this.services.quoteIdentifier(column)).join(", ")})` : "";
|
|
3251
|
+
const query = this.sources.stripTrailingSemicolon(
|
|
3252
|
+
this.services.compileSelectAst(this.services.normalizeSelectAst(cte.query), ctx)
|
|
3253
|
+
);
|
|
3254
|
+
return `${name}${columns} AS (${query})`;
|
|
3128
3255
|
}).join(", ");
|
|
3129
|
-
return `WITH ${
|
|
3256
|
+
return `WITH ${definitions} `;
|
|
3257
|
+
}
|
|
3258
|
+
};
|
|
3259
|
+
|
|
3260
|
+
// src/core/dialect/mssql/update-compiler.ts
|
|
3261
|
+
var MssqlUpdateCompiler = class {
|
|
3262
|
+
constructor(services, sources) {
|
|
3263
|
+
this.services = services;
|
|
3264
|
+
this.sources = sources;
|
|
3265
|
+
this.standardUpdate = new StandardUpdateCompiler(services, sources);
|
|
3266
|
+
}
|
|
3267
|
+
standardUpdate;
|
|
3268
|
+
compile(ast, ctx) {
|
|
3269
|
+
const target = this.sources.compileTableReference(ast.table);
|
|
3270
|
+
const assignments = this.standardUpdate.compileAssignments(ast.set, ast.table, ctx);
|
|
3271
|
+
const output = this.services.compileReturning(ast.returning, ctx);
|
|
3272
|
+
const from = ast.from ? ` FROM ${this.sources.compileFrom(ast.from, ctx)}` : "";
|
|
3273
|
+
const joins = ast.joins ? ast.joins.map((join) => {
|
|
3274
|
+
const table = this.sources.compileFrom(join.table, ctx);
|
|
3275
|
+
const condition = this.services.compileExpression(join.condition, ctx);
|
|
3276
|
+
return ` ${join.kind} JOIN ${table} ON ${condition}`;
|
|
3277
|
+
}).join("") : "";
|
|
3278
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
3279
|
+
return `UPDATE ${target} SET ${assignments}${output}${from}${joins}${where}`;
|
|
3280
|
+
}
|
|
3281
|
+
};
|
|
3282
|
+
|
|
3283
|
+
// src/core/dialect/mssql/compiler-factory.ts
|
|
3284
|
+
var createMssqlCompilerSet = ({ services, sources }) => ({
|
|
3285
|
+
select: new MssqlSelectCompiler(services, sources),
|
|
3286
|
+
insert: new MssqlInsertCompiler(services, sources),
|
|
3287
|
+
update: new MssqlUpdateCompiler(services, sources),
|
|
3288
|
+
delete: new MssqlDeleteCompiler(services, sources)
|
|
3289
|
+
});
|
|
3290
|
+
|
|
3291
|
+
// src/core/dialect/mssql/procedure-compiler.ts
|
|
3292
|
+
var sanitizeVariableSuffix2 = (value) => value.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3293
|
+
var toProcedureParamReference = (value) => value.startsWith("@") ? value : `@${value}`;
|
|
3294
|
+
var MssqlProcedureCompiler = class {
|
|
3295
|
+
constructor(services) {
|
|
3296
|
+
this.services = services;
|
|
3130
3297
|
}
|
|
3131
3298
|
compileProcedureCall(ast) {
|
|
3132
|
-
const ctx = this.createCompilerContext();
|
|
3133
|
-
const qualifiedName = ast.ref.schema ? `${this.quoteIdentifier(ast.ref.schema)}.${this.quoteIdentifier(ast.ref.name)}` : this.quoteIdentifier(ast.ref.name);
|
|
3299
|
+
const ctx = this.services.createCompilerContext();
|
|
3300
|
+
const qualifiedName = ast.ref.schema ? `${this.services.quoteIdentifier(ast.ref.schema)}.${this.services.quoteIdentifier(ast.ref.name)}` : this.services.quoteIdentifier(ast.ref.name);
|
|
3134
3301
|
const declarations = [];
|
|
3135
3302
|
const assignments = [];
|
|
3136
3303
|
const execArgs = [];
|
|
@@ -3141,7 +3308,7 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
3141
3308
|
if (!param.value) {
|
|
3142
3309
|
throw new Error(`Procedure parameter "${param.name}" requires a value for direction "in".`);
|
|
3143
3310
|
}
|
|
3144
|
-
execArgs.push(`${targetParam} = ${this.compileOperand(param.value, ctx)}`);
|
|
3311
|
+
execArgs.push(`${targetParam} = ${this.services.compileOperand(param.value, ctx)}`);
|
|
3145
3312
|
return;
|
|
3146
3313
|
}
|
|
3147
3314
|
if (!param.dbType) {
|
|
@@ -3156,7 +3323,7 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
3156
3323
|
if (!param.value) {
|
|
3157
3324
|
throw new Error(`Procedure parameter "${param.name}" requires a value for direction "inout".`);
|
|
3158
3325
|
}
|
|
3159
|
-
assignments.push(`SET ${variable} = ${this.compileOperand(param.value, ctx)};`);
|
|
3326
|
+
assignments.push(`SET ${variable} = ${this.services.compileOperand(param.value, ctx)};`);
|
|
3160
3327
|
}
|
|
3161
3328
|
execArgs.push(`${targetParam} = ${variable} OUTPUT`);
|
|
3162
3329
|
outVars.push({ variable, name: param.name });
|
|
@@ -3167,7 +3334,7 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
3167
3334
|
const argsSql = execArgs.length ? ` ${execArgs.join(", ")}` : "";
|
|
3168
3335
|
statements.push(`EXEC ${qualifiedName}${argsSql};`);
|
|
3169
3336
|
if (outVars.length) {
|
|
3170
|
-
const selectOut = outVars.map(({ variable, name }) => `${variable} AS ${this.quoteIdentifier(name)}`).join(", ");
|
|
3337
|
+
const selectOut = outVars.map(({ variable, name }) => `${variable} AS ${this.services.quoteIdentifier(name)}`).join(", ");
|
|
3171
3338
|
statements.push(`SELECT ${selectOut};`);
|
|
3172
3339
|
}
|
|
3173
3340
|
return {
|
|
@@ -3181,6 +3348,38 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
3181
3348
|
}
|
|
3182
3349
|
};
|
|
3183
3350
|
|
|
3351
|
+
// src/core/dialect/mssql/index.ts
|
|
3352
|
+
var SqlServerDialect = class extends SqlDialectBase {
|
|
3353
|
+
dialect = "mssql";
|
|
3354
|
+
procedureCompiler;
|
|
3355
|
+
constructor() {
|
|
3356
|
+
super({
|
|
3357
|
+
functionStrategy: new MssqlFunctionStrategy(),
|
|
3358
|
+
returningStrategy: new MssqlOutputStrategy(),
|
|
3359
|
+
compilerFactory: createMssqlCompilerSet,
|
|
3360
|
+
supportsDmlReturning: true
|
|
3361
|
+
});
|
|
3362
|
+
this.procedureCompiler = new MssqlProcedureCompiler({
|
|
3363
|
+
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
3364
|
+
createCompilerContext: () => this.createCompilerContext(),
|
|
3365
|
+
compileOperand: (node, ctx) => this.compileOperand(node, ctx)
|
|
3366
|
+
});
|
|
3367
|
+
}
|
|
3368
|
+
quoteIdentifier(id) {
|
|
3369
|
+
return `[${id}]`;
|
|
3370
|
+
}
|
|
3371
|
+
compileJsonPath(node) {
|
|
3372
|
+
const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
3373
|
+
return `JSON_VALUE(${column}, '${node.path}')`;
|
|
3374
|
+
}
|
|
3375
|
+
formatPlaceholder(index) {
|
|
3376
|
+
return `@p${index}`;
|
|
3377
|
+
}
|
|
3378
|
+
compileProcedureCall(ast) {
|
|
3379
|
+
return this.procedureCompiler.compileProcedureCall(ast);
|
|
3380
|
+
}
|
|
3381
|
+
};
|
|
3382
|
+
|
|
3184
3383
|
// src/core/dialect/dialect-factory.ts
|
|
3185
3384
|
var DialectFactory = class {
|
|
3186
3385
|
static registry = /* @__PURE__ */ new Map();
|
|
@@ -21658,13 +21857,26 @@ export {
|
|
|
21658
21857
|
MorphMany,
|
|
21659
21858
|
MorphOne,
|
|
21660
21859
|
MorphTo,
|
|
21860
|
+
MssqlDeleteCompiler,
|
|
21861
|
+
MssqlInsertCompiler,
|
|
21862
|
+
MssqlOutputStrategy,
|
|
21863
|
+
MssqlProcedureCompiler,
|
|
21864
|
+
MssqlSelectCompiler,
|
|
21865
|
+
MssqlUpdateCompiler,
|
|
21661
21866
|
MySqlDialect,
|
|
21867
|
+
MySqlProcedureCompiler,
|
|
21868
|
+
MySqlUpsertStrategy,
|
|
21662
21869
|
NestedSetStrategy,
|
|
21870
|
+
NoReturningStrategy,
|
|
21871
|
+
NoUpsertStrategy,
|
|
21663
21872
|
Orm,
|
|
21664
21873
|
OrmSession,
|
|
21665
21874
|
Pattern,
|
|
21666
21875
|
Pool,
|
|
21667
21876
|
PostgresDialect,
|
|
21877
|
+
PostgresProcedureCompiler,
|
|
21878
|
+
PostgresReturningStrategy,
|
|
21879
|
+
PostgresUpsertStrategy,
|
|
21668
21880
|
PrimaryKey,
|
|
21669
21881
|
ProcedureCallBuilder,
|
|
21670
21882
|
PrototypeMaterializationStrategy,
|
|
@@ -21673,8 +21885,19 @@ export {
|
|
|
21673
21885
|
RelationKinds,
|
|
21674
21886
|
STANDARD_COLUMN_TYPES,
|
|
21675
21887
|
SelectQueryBuilder,
|
|
21888
|
+
SqlDialectBase,
|
|
21676
21889
|
SqlServerDialect,
|
|
21677
21890
|
SqliteDialect,
|
|
21891
|
+
SqliteReturningStrategy,
|
|
21892
|
+
SqliteUpsertStrategy,
|
|
21893
|
+
StandardDeleteCompiler,
|
|
21894
|
+
StandardInsertCompiler,
|
|
21895
|
+
StandardLimitOffsetPagination,
|
|
21896
|
+
StandardReturningStrategy,
|
|
21897
|
+
StandardSelectCompiler,
|
|
21898
|
+
StandardSqlSourceCompiler,
|
|
21899
|
+
StandardTableFunctionStrategy,
|
|
21900
|
+
StandardUpdateCompiler,
|
|
21678
21901
|
StringTypeStrategy,
|
|
21679
21902
|
TagIndex,
|
|
21680
21903
|
Title,
|
|
@@ -21761,6 +21984,7 @@ export {
|
|
|
21761
21984
|
createEntityFromRow,
|
|
21762
21985
|
createEntityProxy,
|
|
21763
21986
|
createExecutorFromQueryRunner,
|
|
21987
|
+
createMssqlCompilerSet,
|
|
21764
21988
|
createMssqlExecutor,
|
|
21765
21989
|
createMysqlExecutor,
|
|
21766
21990
|
createPooledExecutorFactory,
|