pqb 0.68.0 → 0.69.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/index.mjs CHANGED
@@ -1681,6 +1681,44 @@ const columnCode = (type, ctx, key, code) => {
1681
1681
  if (data.modifyQuery && !ctx.migration) addCode(code, `.modifyQuery(${data.modifyQuery.toString()})`);
1682
1682
  return code.length === 1 && typeof code[0] === "string" ? code[0] : code;
1683
1683
  };
1684
+ /**
1685
+ * generic utility to add a parser to the query object
1686
+ * @param query - the query object, it will be mutated
1687
+ * @param key - the name of the column in the data loaded by the query
1688
+ * @param parser - function to process the value of the column with.
1689
+ */
1690
+ const setParserToQuery = (query, key, parser) => {
1691
+ if (parser) if (query.parsers) query.parsers[key] = parser;
1692
+ else query.parsers = { [key]: parser };
1693
+ else if (query.parsers) delete query.parsers[key];
1694
+ };
1695
+ const getQueryParsers = (q, hookSelect) => {
1696
+ if (hookSelect) {
1697
+ const parsers = { ...q.q.parsers };
1698
+ const { defaultParsers } = q.q;
1699
+ if (defaultParsers) for (const [key, value] of hookSelect) {
1700
+ const parser = defaultParsers[key];
1701
+ if (parser) parsers[value.as || key] = parser;
1702
+ }
1703
+ return parsers;
1704
+ }
1705
+ return q.q.select ? q.q.parsers : q.q.defaultParsers;
1706
+ };
1707
+ const addColumnParserToQuery = (q, key, column) => {
1708
+ if (column._parse) setObjectValueImmutable(q, "parsers", key, column._parse);
1709
+ };
1710
+ const setValueParserToQuery = (q, column) => {
1711
+ addColumnParserToQuery(q, "v", column);
1712
+ };
1713
+ const getValueParser = (parsers) => {
1714
+ return parsers?.v;
1715
+ };
1716
+ const setValueParser = (q, parser) => {
1717
+ setObjectValueImmutable(q, "parsers", "v", parser);
1718
+ };
1719
+ const addParserForRawExpression = (q, key, raw) => {
1720
+ if (raw.result.value) addColumnParserToQuery(q.q, key, raw.result.value);
1721
+ };
1684
1722
  var CustomTypeColumn = class extends Column {
1685
1723
  constructor(schema, typeName, typeSchema, extension) {
1686
1724
  super(schema, schema.unknown(), schema.unknown(), schema.unknown());
@@ -1728,9 +1766,6 @@ var EnumColumn = class extends Column {
1728
1766
  return `"${index === -1 ? name : `${name.slice(0, index)}"."${name.slice(index + 1)}`}"`;
1729
1767
  }
1730
1768
  };
1731
- const addColumnParserToQuery = (q, key, column) => {
1732
- if (column._parse) setObjectValueImmutable(q, "parsers", key, column._parse);
1733
- };
1734
1769
  const setColumnDefaultParse = (column, parse) => {
1735
1770
  column.data.parse = parse;
1736
1771
  column._parse = (input) => input === null ? null : parse(input);
@@ -1772,174 +1807,6 @@ const setColumnEncode = (column, fn, inputSchema) => {
1772
1807
  const getColumnBaseType = (column, domainsMap, type) => {
1773
1808
  return column instanceof EnumColumn ? "text" : column instanceof DomainColumn ? domainsMap[column.dataType]?.dataType : type;
1774
1809
  };
1775
- const getValueKey = Symbol("get");
1776
- let moveMutativeQueryToCte$1;
1777
- const setMoveMutativeQueryToCte = (fn) => {
1778
- moveMutativeQueryToCte$1 = fn;
1779
- };
1780
- let prepareSubQueryForSql$1;
1781
- const setPrepareSubQueryForSql = (fn) => {
1782
- prepareSubQueryForSql$1 = fn;
1783
- };
1784
- let dbClass;
1785
- const setDb = (db) => {
1786
- dbClass = db;
1787
- };
1788
- function setQueryOperators(query, operators) {
1789
- const q = query.q;
1790
- if (q.operators !== operators) {
1791
- q.operators = operators;
1792
- Object.assign(query, operators);
1793
- }
1794
- return query;
1795
- }
1796
- /**
1797
- * Makes operator function that has `_op` property.
1798
- *
1799
- * @param _op - function to turn the operator call into SQL.
1800
- */
1801
- const make = (_op) => {
1802
- return Object.assign(function(value) {
1803
- const { q } = this;
1804
- const val = prepareOpArg(this, value);
1805
- (q.chain ??= []).push(_op, val || value);
1806
- if (q.parsers?.[getValueKey]) setObjectValueImmutable(q, "parsers", getValueKey, void 0);
1807
- return setQueryOperators(this, boolean);
1808
- }, { _op });
1809
- };
1810
- const makeVarArg = (_op) => {
1811
- return Object.assign(function(...args) {
1812
- const { q } = this;
1813
- args.forEach((arg, i) => {
1814
- const val = prepareOpArg(this, arg);
1815
- if (val) args[i] = val;
1816
- });
1817
- (q.chain ??= []).push(_op, args);
1818
- if (q.parsers?.[getValueKey]) setObjectValueImmutable(q, "parsers", getValueKey, void 0);
1819
- return setQueryOperators(this, boolean);
1820
- }, { _op });
1821
- };
1822
- const prepareOpArg = (q, arg) => {
1823
- return arg instanceof dbClass ? prepareSubQueryForSql$1(q, arg) : void 0;
1824
- };
1825
- const quoteValue = (arg, ctx, quotedAs, IN) => {
1826
- if (arg && typeof arg === "object") {
1827
- if (IN && isIterable(arg)) return `(${(Array.isArray(arg) ? arg : [...arg]).map((value) => addValue(ctx.values, value)).join(", ")})`;
1828
- if (isExpression(arg)) return arg.toSQL(ctx, quotedAs);
1829
- if ("toSQL" in arg) return `(${moveMutativeQueryToCte$1(ctx, arg)})`;
1830
- if (!(arg instanceof Date) && !Array.isArray(arg)) arg = JSON.stringify(arg);
1831
- }
1832
- return addValue(ctx.values, arg);
1833
- };
1834
- const quoteLikeValue = (arg, ctx, quotedAs, jsonArray) => {
1835
- if (arg && typeof arg === "object") {
1836
- if (!jsonArray && Array.isArray(arg)) return `(${arg.map((value) => addValue(ctx.values, value)).join(", ")})`;
1837
- if (isExpression(arg)) return arg.toSQL(ctx, quotedAs);
1838
- if ("toSQL" in arg) return `replace(replace((${moveMutativeQueryToCte$1(ctx, arg)}), '%', '\\\\%'), '_', '\\\\_')`;
1839
- }
1840
- return addValue(ctx.values, arg.replace(/[%_]/g, "\\$&"));
1841
- };
1842
- const base = {
1843
- equals: make((key, value, ctx, quotedAs) => value === null ? `${key} IS NULL` : `${key} = ${quoteValue(value, ctx, quotedAs)}`),
1844
- not: make((key, value, ctx, quotedAs) => value === null ? `${key} IS NOT NULL` : `${key} <> ${quoteValue(value, ctx, quotedAs)}`),
1845
- in: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "false" : `${key} IN ${quoteValue(value, ctx, quotedAs, true)}`),
1846
- notIn: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "true" : `NOT ${key} IN ${quoteValue(value, ctx, quotedAs, true)}`)
1847
- };
1848
- const ord = {
1849
- ...base,
1850
- lt: make((key, value, ctx, quotedAs) => `${key} < ${quoteValue(value, ctx, quotedAs)}`),
1851
- lte: make((key, value, ctx, quotedAs) => `${key} <= ${quoteValue(value, ctx, quotedAs)}`),
1852
- gt: make((key, value, ctx, quotedAs) => `${key} > ${quoteValue(value, ctx, quotedAs)}`),
1853
- gte: make((key, value, ctx, quotedAs) => `${key} >= ${quoteValue(value, ctx, quotedAs)}`),
1854
- between: make((key, [from, to], ctx, quotedAs) => `${key} BETWEEN ${quoteValue(from, ctx, quotedAs)} AND ${quoteValue(to, ctx, quotedAs)}`)
1855
- };
1856
- const boolean = {
1857
- ...ord,
1858
- and: make((key, value, ctx, quotedAs) => `${key} AND ${value.q.expr.toSQL(ctx, quotedAs)}`),
1859
- or: make((key, value, ctx, quotedAs) => `(${key}) OR (${value.q.expr.toSQL(ctx, quotedAs)})`)
1860
- };
1861
- const text = {
1862
- ...base,
1863
- contains: make((key, value, ctx, quotedAs) => `${key} ILIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
1864
- containsSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
1865
- startsWith: make((key, value, ctx, quotedAs) => `${key} ILIKE ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
1866
- startsWithSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
1867
- endsWith: make((key, value, ctx, quotedAs) => `${key} ILIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)}`),
1868
- endsWithSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)}`)
1869
- };
1870
- const ordinalText = {
1871
- ...ord,
1872
- ...text
1873
- };
1874
- const encodeJsonPath = (ctx, path) => addValue(ctx.values, `{${Array.isArray(path) ? path.join(", ") : path}}`);
1875
- const jsonPathQueryOp = (key, [path, options], ctx) => `jsonb_path_query_first(${key}, ${addValue(ctx.values, path)}${options?.vars ? `, ${addValue(ctx.values, JSON.stringify(options.vars))}${options.silent ? ", true" : ""}` : options?.silent ? ", NULL, true" : ""})`;
1876
- const shouldEncodeJson = (ctx) => ctx.q.adapter.driverAdapter.schemaConfig?.jsonEncodedByDriver === false;
1877
- const quoteJsonValue = (arg, ctx, quotedAs, IN) => {
1878
- if (arg && typeof arg === "object") {
1879
- if (IN && Array.isArray(arg)) return `(${arg.map((value) => shouldEncodeJson(ctx) ? addValue(ctx.values, JSON.stringify(value)) : addValue(ctx.values, value)).join(", ")})`;
1880
- if (Array.isArray(arg)) return shouldEncodeJson(ctx) ? addValue(ctx.values, JSON.stringify(arg)) : addValue(ctx.values, arg);
1881
- if (isExpression(arg)) return "to_jsonb(" + arg.toSQL(ctx, quotedAs) + ")";
1882
- if ("toSQL" in arg) return `to_jsonb((${moveMutativeQueryToCte$1(ctx, arg)}))`;
1883
- }
1884
- return addValue(ctx.values, JSON.stringify(arg)) + "::jsonb";
1885
- };
1886
- const serializeJsonValue = (arg, ctx, quotedAs) => {
1887
- if (arg && typeof arg === "object") {
1888
- if (isExpression(arg)) return "to_jsonb(" + arg.toSQL(ctx, quotedAs) + ")";
1889
- if ("toSQL" in arg) return `to_jsonb((${moveMutativeQueryToCte$1(ctx, arg)}))`;
1890
- }
1891
- return addValue(ctx.values, JSON.stringify(arg));
1892
- };
1893
- const Operators = {
1894
- any: base,
1895
- boolean,
1896
- ordinalText,
1897
- number: ord,
1898
- date: ord,
1899
- time: ord,
1900
- text,
1901
- json: {
1902
- ...ord,
1903
- equals: make((key, value, ctx, quotedAs) => value === null ? `nullif(${key}, 'null'::jsonb) IS NULL` : `${key} = ${quoteJsonValue(value, ctx, quotedAs)}`),
1904
- not: make((key, value, ctx, quotedAs) => value === null ? `nullif(${key}, 'null'::jsonb) IS NOT NULL` : `${key} != ${quoteJsonValue(value, ctx, quotedAs)}`),
1905
- in: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "false" : `${key} IN ${quoteJsonValue(value, ctx, quotedAs, true)}`),
1906
- notIn: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "true" : `NOT ${key} IN ${quoteJsonValue(value, ctx, quotedAs, true)}`),
1907
- jsonPathQueryFirst: Object.assign(function(path, options) {
1908
- const { q, columnTypes } = this;
1909
- const chain = q.chain ??= [];
1910
- chain.push(jsonPathQueryOp, [path, options]);
1911
- if (q.parsers?.[getValueKey]) setObjectValueImmutable(q, "parsers", getValueKey, void 0);
1912
- if (options?.type) {
1913
- const type = options.type(columnTypes);
1914
- addColumnParserToQuery(q, getValueKey, type);
1915
- chain.push = (...args) => {
1916
- chain.push = Array.prototype.push;
1917
- chain.push((s) => `${s}::${type.dataType}`, emptyArray);
1918
- return chain.push(...args);
1919
- };
1920
- return setQueryOperators(this, type.operators);
1921
- }
1922
- return this;
1923
- }, { _op: jsonPathQueryOp }),
1924
- jsonSupersetOf: make((key, value, ctx, quotedAs) => `${key} @> ${quoteValue(value, ctx, quotedAs)}`),
1925
- jsonSubsetOf: make((key, value, ctx, quotedAs) => `${key} <@ ${quoteValue(value, ctx, quotedAs)}`),
1926
- jsonSet: makeVarArg((key, [path, value], ctx, quotedAs) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)})`),
1927
- jsonReplace: makeVarArg((key, [path, value], ctx, quotedAs) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)}, false)`),
1928
- jsonInsert: makeVarArg((key, [path, value, options], ctx, quotedAs) => `jsonb_insert(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)}${options?.after ? ", true" : ""})`),
1929
- jsonRemove: makeVarArg((key, [path], ctx) => `(${key} #- ${encodeJsonPath(ctx, path)})`)
1930
- },
1931
- array: {
1932
- ...ord,
1933
- has: make((key, value, ctx, quotedAs) => `${quoteValue(value, ctx, quotedAs)} = ANY(${key})`),
1934
- hasEvery: make((key, value, ctx, quotedAs) => `${key} @> ${quoteValue(value, ctx, quotedAs)}`),
1935
- hasSome: make((key, value, ctx, quotedAs) => `${key} && ${quoteValue(value, ctx, quotedAs)}`),
1936
- containedIn: make((key, value, ctx, quotedAs) => `${key} <@ ${quoteValue(value, ctx, quotedAs)}`),
1937
- length: make((key, value, ctx, quotedAs) => {
1938
- const expr = `COALESCE(array_length(${key}, 1), 0)`;
1939
- return typeof value === "number" ? `${expr} = ${quoteValue(value, ctx, quotedAs)}` : Object.keys(value).map((key) => ord[key]._op(expr, value[key], ctx, quotedAs)).join(" AND ");
1940
- })
1941
- }
1942
- };
1943
1810
  const dateToString = (value) => value.toISOString();
1944
1811
  const dateTimeEncode = (value) => {
1945
1812
  return typeof value === "number" ? new Date(value) : value;
@@ -2067,7 +1934,6 @@ var ArrayColumn = class ArrayColumn extends Column {
2067
1934
  this.dataType = "array";
2068
1935
  this.operators = Operators.array;
2069
1936
  item.data.isNullable = true;
2070
- setColumnDefaultParse(this, (input) => parse$1.call(this, input));
2071
1937
  if (defaultEncode) setColumnDefaultEncode(this, defaultEncode);
2072
1938
  this.data.item = item instanceof ArrayColumn ? item.data.item : item;
2073
1939
  this.data.name = item.data.name;
@@ -2093,54 +1959,6 @@ var ArrayColumn = class ArrayColumn extends Column {
2093
1959
  return columnCode(this, ctx, key, code);
2094
1960
  }
2095
1961
  };
2096
- const parse$1 = function(source) {
2097
- if (typeof source !== "string") return source;
2098
- const entries = [];
2099
- parsePostgresArray(source, entries, this.data.item.data.parseItem);
2100
- return entries;
2101
- };
2102
- /**
2103
- * based on https://github.com/bendrucker/postgres-array/tree/master
2104
- * and slightly optimized
2105
- */
2106
- const parsePostgresArray = (source, entries, transform) => {
2107
- let pos = 0;
2108
- if (source[0] === "[") {
2109
- pos = source.indexOf("=") + 1;
2110
- if (!pos) pos = source.length;
2111
- }
2112
- if (source[pos] === "{") pos++;
2113
- let recorded = "";
2114
- while (pos < source.length) {
2115
- const character = source[pos++];
2116
- if (character === "{") {
2117
- const innerEntries = [];
2118
- entries.push(innerEntries);
2119
- pos += parsePostgresArray(source.slice(pos - 1), innerEntries, transform) - 1;
2120
- } else if (character === "}") {
2121
- if (recorded) entries.push(recorded === "NULL" ? null : transform ? transform(recorded) : recorded);
2122
- return pos;
2123
- } else if (character === "\"") {
2124
- let esc = false;
2125
- let rec = "";
2126
- while (pos < source.length) {
2127
- let char;
2128
- while ((char = source[pos++]) === "\\") if (!(esc = !esc)) rec += "\\";
2129
- if (esc) esc = false;
2130
- else if (char === "\"") break;
2131
- rec += char;
2132
- }
2133
- entries.push(transform ? transform(rec) : rec);
2134
- recorded = "";
2135
- } else if (character === ",") {
2136
- if (recorded) {
2137
- entries.push(recorded === "NULL" ? null : transform ? transform(recorded) : recorded);
2138
- recorded = "";
2139
- }
2140
- } else recorded += character;
2141
- }
2142
- return pos;
2143
- };
2144
1962
  const encodeJson = (x) => x === null ? x : JSON.stringify(x);
2145
1963
  var JSONColumn = class extends Column {
2146
1964
  constructor(schema, __inputType, encodedByDriver = true) {
@@ -2396,6 +2214,202 @@ const defaultSchemaConfig = (options) => {
2396
2214
  return schemaConfig;
2397
2215
  };
2398
2216
  const internalSchemaConfig = defaultSchemaConfig();
2217
+ var BooleanColumn = class BooleanColumn extends Column {
2218
+ static get instance() {
2219
+ return this._instance ??= new BooleanColumn(internalSchemaConfig);
2220
+ }
2221
+ static get instanceSkipValueToArray() {
2222
+ let instance = this._instanceSkipValueToArray;
2223
+ if (!instance) {
2224
+ instance = this._instanceSkipValueToArray = Object.create(this.instance);
2225
+ instance.data.skipValueToArray = true;
2226
+ }
2227
+ return instance;
2228
+ }
2229
+ constructor(schema) {
2230
+ super(schema, schema.boolean());
2231
+ this.dataType = "bool";
2232
+ this.operators = Operators.boolean;
2233
+ this.data.alias = "boolean";
2234
+ this.data.parseItem = parseItem;
2235
+ }
2236
+ toCode(ctx, key) {
2237
+ return columnCode(this, ctx, key, "boolean()");
2238
+ }
2239
+ };
2240
+ const parseItem = (input) => input[0] === "t";
2241
+ let moveMutativeQueryToCte$1;
2242
+ const setMoveMutativeQueryToCte = (fn) => {
2243
+ moveMutativeQueryToCte$1 = fn;
2244
+ };
2245
+ let prepareSubQueryForSql$1;
2246
+ const setPrepareSubQueryForSql = (fn) => {
2247
+ prepareSubQueryForSql$1 = fn;
2248
+ };
2249
+ let dbClass;
2250
+ const setDb = (db) => {
2251
+ dbClass = db;
2252
+ };
2253
+ function setQueryOperators(query, operators) {
2254
+ const q = query.q;
2255
+ if (q.operators !== operators) {
2256
+ q.operators = operators;
2257
+ Object.assign(query, operators);
2258
+ }
2259
+ return query;
2260
+ }
2261
+ /**
2262
+ * Makes operator function that has `_op` property.
2263
+ *
2264
+ * @param _op - function to turn the operator call into SQL.
2265
+ */
2266
+ const make = (_op) => {
2267
+ return Object.assign(function(value) {
2268
+ const { q } = this;
2269
+ const val = prepareOpArg(this, value);
2270
+ (q.chain ??= []).push(_op, val || value);
2271
+ if (getValueParser(q.parsers)) setValueParser(q, void 0);
2272
+ q.getColumn = BooleanColumn.instance;
2273
+ return setQueryOperators(this, boolean);
2274
+ }, { _op });
2275
+ };
2276
+ const makeVarArg = (_op) => {
2277
+ return Object.assign(function(...args) {
2278
+ const { q } = this;
2279
+ args.forEach((arg, i) => {
2280
+ const val = prepareOpArg(this, arg);
2281
+ if (val) args[i] = val;
2282
+ });
2283
+ (q.chain ??= []).push(_op, args);
2284
+ if (getValueParser(q.parsers)) setValueParser(q, void 0);
2285
+ return setQueryOperators(this, boolean);
2286
+ }, { _op });
2287
+ };
2288
+ const prepareOpArg = (q, arg) => {
2289
+ return arg instanceof dbClass ? prepareSubQueryForSql$1(q, arg) : void 0;
2290
+ };
2291
+ const quoteValue = (arg, ctx, quotedAs, IN) => {
2292
+ if (arg && typeof arg === "object") {
2293
+ if (IN && isIterable(arg)) return `(${(Array.isArray(arg) ? arg : [...arg]).map((value) => addValue(ctx.values, value)).join(", ")})`;
2294
+ if (isExpression(arg)) return arg.toSQL(ctx, quotedAs);
2295
+ if ("toSQL" in arg) return `(${moveMutativeQueryToCte$1(ctx, arg)})`;
2296
+ if (!(arg instanceof Date) && !Array.isArray(arg)) arg = JSON.stringify(arg);
2297
+ }
2298
+ return addValue(ctx.values, arg);
2299
+ };
2300
+ const quoteLikeValue = (arg, ctx, quotedAs, jsonArray) => {
2301
+ if (arg && typeof arg === "object") {
2302
+ if (!jsonArray && Array.isArray(arg)) return `(${arg.map((value) => addValue(ctx.values, value)).join(", ")})`;
2303
+ if (isExpression(arg)) return arg.toSQL(ctx, quotedAs);
2304
+ if ("toSQL" in arg) return `replace(replace((${moveMutativeQueryToCte$1(ctx, arg)}), '%', '\\\\%'), '_', '\\\\_')`;
2305
+ }
2306
+ return addValue(ctx.values, arg.replace(/[%_]/g, "\\$&"));
2307
+ };
2308
+ const base = {
2309
+ equals: make((key, value, ctx, quotedAs) => value === null ? `${key} IS NULL` : `${key} = ${quoteValue(value, ctx, quotedAs)}`),
2310
+ not: make((key, value, ctx, quotedAs) => value === null ? `${key} IS NOT NULL` : `${key} <> ${quoteValue(value, ctx, quotedAs)}`),
2311
+ isDistinctFrom: make((key, value, ctx, quotedAs) => `${key} IS DISTINCT FROM ${quoteValue(value, ctx, quotedAs)}`),
2312
+ isNotDistinctFrom: make((key, value, ctx, quotedAs) => `${key} IS NOT DISTINCT FROM ${quoteValue(value, ctx, quotedAs)}`),
2313
+ in: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "false" : `${key} IN ${quoteValue(value, ctx, quotedAs, true)}`),
2314
+ notIn: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "true" : `NOT ${key} IN ${quoteValue(value, ctx, quotedAs, true)}`)
2315
+ };
2316
+ const ord = {
2317
+ ...base,
2318
+ lt: make((key, value, ctx, quotedAs) => `${key} < ${quoteValue(value, ctx, quotedAs)}`),
2319
+ lte: make((key, value, ctx, quotedAs) => `${key} <= ${quoteValue(value, ctx, quotedAs)}`),
2320
+ gt: make((key, value, ctx, quotedAs) => `${key} > ${quoteValue(value, ctx, quotedAs)}`),
2321
+ gte: make((key, value, ctx, quotedAs) => `${key} >= ${quoteValue(value, ctx, quotedAs)}`),
2322
+ between: make((key, [from, to], ctx, quotedAs) => `${key} BETWEEN ${quoteValue(from, ctx, quotedAs)} AND ${quoteValue(to, ctx, quotedAs)}`)
2323
+ };
2324
+ const boolean = {
2325
+ ...ord,
2326
+ and: make((key, value, ctx, quotedAs) => `${key} AND ${value.q.expr.toSQL(ctx, quotedAs)}`),
2327
+ or: make((key, value, ctx, quotedAs) => `(${key}) OR (${value.q.expr.toSQL(ctx, quotedAs)})`)
2328
+ };
2329
+ const text = {
2330
+ ...base,
2331
+ contains: make((key, value, ctx, quotedAs) => `${key} ILIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
2332
+ containsSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
2333
+ startsWith: make((key, value, ctx, quotedAs) => `${key} ILIKE ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
2334
+ startsWithSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
2335
+ endsWith: make((key, value, ctx, quotedAs) => `${key} ILIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)}`),
2336
+ endsWithSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)}`)
2337
+ };
2338
+ const ordinalText = {
2339
+ ...ord,
2340
+ ...text
2341
+ };
2342
+ const encodeJsonPath = (ctx, path) => addValue(ctx.values, `{${Array.isArray(path) ? path.join(", ") : path}}`);
2343
+ const jsonPathQueryOp = (key, [path, options], ctx) => `jsonb_path_query_first(${key}, ${addValue(ctx.values, path)}${options?.vars ? `, ${addValue(ctx.values, JSON.stringify(options.vars))}${options.silent ? ", true" : ""}` : options?.silent ? ", NULL, true" : ""})`;
2344
+ const shouldEncodeJson = (ctx) => ctx.q.adapter.driverAdapter.schemaConfig?.jsonEncodedByDriver === false;
2345
+ const quoteJsonValue = (arg, ctx, quotedAs, IN) => {
2346
+ if (arg && typeof arg === "object") {
2347
+ if (IN && Array.isArray(arg)) return `(${arg.map((value) => shouldEncodeJson(ctx) ? addValue(ctx.values, JSON.stringify(value)) : addValue(ctx.values, value)).join(", ")})`;
2348
+ if (Array.isArray(arg)) return shouldEncodeJson(ctx) ? addValue(ctx.values, JSON.stringify(arg)) : addValue(ctx.values, arg);
2349
+ if (isExpression(arg)) return "to_jsonb(" + arg.toSQL(ctx, quotedAs) + ")";
2350
+ if ("toSQL" in arg) return `to_jsonb((${moveMutativeQueryToCte$1(ctx, arg)}))`;
2351
+ }
2352
+ return shouldEncodeJson(ctx) ? addValue(ctx.values, JSON.stringify(arg)) : addValue(ctx.values, arg);
2353
+ };
2354
+ const serializeJsonValue = (arg, ctx, quotedAs) => {
2355
+ if (arg && typeof arg === "object") {
2356
+ if (isExpression(arg)) return "to_jsonb(" + arg.toSQL(ctx, quotedAs) + ")";
2357
+ if ("toSQL" in arg) return `to_jsonb((${moveMutativeQueryToCte$1(ctx, arg)}))`;
2358
+ }
2359
+ return addValue(ctx.values, JSON.stringify(arg));
2360
+ };
2361
+ const Operators = {
2362
+ any: base,
2363
+ boolean,
2364
+ ordinalText,
2365
+ number: ord,
2366
+ date: ord,
2367
+ time: ord,
2368
+ text,
2369
+ json: {
2370
+ ...ord,
2371
+ equals: make((key, value, ctx, quotedAs) => value === null ? `nullif(${key}, 'null'::jsonb) IS NULL` : `${key} = ${quoteJsonValue(value, ctx, quotedAs)}`),
2372
+ not: make((key, value, ctx, quotedAs) => value === null ? `nullif(${key}, 'null'::jsonb) IS NOT NULL` : `${key} != ${quoteJsonValue(value, ctx, quotedAs)}`),
2373
+ isDistinctFrom: make((key, value, ctx, quotedAs) => `${key} IS DISTINCT FROM ${quoteJsonValue(value, ctx, quotedAs)}`),
2374
+ isNotDistinctFrom: make((key, value, ctx, quotedAs) => `${key} IS NOT DISTINCT FROM ${quoteJsonValue(value, ctx, quotedAs)}`),
2375
+ in: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "false" : `${key} IN ${quoteJsonValue(value, ctx, quotedAs, true)}`),
2376
+ notIn: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "true" : `NOT ${key} IN ${quoteJsonValue(value, ctx, quotedAs, true)}`),
2377
+ jsonPathQueryFirst: Object.assign(function(path, options) {
2378
+ const { q, columnTypes } = this;
2379
+ const chain = q.chain ??= [];
2380
+ chain.push(jsonPathQueryOp, [path, options]);
2381
+ if (getValueParser(q.parsers)) setValueParser(q, void 0);
2382
+ if (options?.type) {
2383
+ const type = options.type(columnTypes);
2384
+ setValueParserToQuery(q, type);
2385
+ chain.push = (...args) => {
2386
+ chain.push = Array.prototype.push;
2387
+ chain.push((s) => `${s}::${type.dataType}`, emptyArray);
2388
+ return chain.push(...args);
2389
+ };
2390
+ return setQueryOperators(this, type.operators);
2391
+ }
2392
+ return this;
2393
+ }, { _op: jsonPathQueryOp }),
2394
+ jsonSupersetOf: make((key, value, ctx, quotedAs) => `${key} @> ${quoteValue(value, ctx, quotedAs)}`),
2395
+ jsonSubsetOf: make((key, value, ctx, quotedAs) => `${key} <@ ${quoteValue(value, ctx, quotedAs)}`),
2396
+ jsonSet: makeVarArg((key, [path, value], ctx, quotedAs) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)})`),
2397
+ jsonReplace: makeVarArg((key, [path, value], ctx, quotedAs) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)}, false)`),
2398
+ jsonInsert: makeVarArg((key, [path, value, options], ctx, quotedAs) => `jsonb_insert(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)}${options?.after ? ", true" : ""})`),
2399
+ jsonRemove: makeVarArg((key, [path], ctx) => `(${key} #- ${encodeJsonPath(ctx, path)})`)
2400
+ },
2401
+ array: {
2402
+ ...ord,
2403
+ has: make((key, value, ctx, quotedAs) => `${quoteValue(value, ctx, quotedAs)} = ANY(${key})`),
2404
+ hasEvery: make((key, value, ctx, quotedAs) => `${key} @> ${quoteValue(value, ctx, quotedAs)}`),
2405
+ hasSome: make((key, value, ctx, quotedAs) => `${key} && ${quoteValue(value, ctx, quotedAs)}`),
2406
+ containedIn: make((key, value, ctx, quotedAs) => `${key} <@ ${quoteValue(value, ctx, quotedAs)}`),
2407
+ length: make((key, value, ctx, quotedAs) => {
2408
+ const expr = `COALESCE(array_length(${key}, 1), 0)`;
2409
+ return typeof value === "number" ? `${expr} = ${quoteValue(value, ctx, quotedAs)}` : Object.keys(value).map((key) => ord[key]._op(expr, value[key], ctx, quotedAs)).join(" AND ");
2410
+ })
2411
+ }
2412
+ };
2399
2413
  var TextBaseColumn = class extends Column {
2400
2414
  constructor(schema, schemaType = schema.stringSchema()) {
2401
2415
  super(schema, schemaType);
@@ -2755,22 +2769,6 @@ var CitextColumn = class extends TextBaseColumn {
2755
2769
  return textColumnToCode(this, ctx, key);
2756
2770
  }
2757
2771
  };
2758
- var BooleanColumn = class BooleanColumn extends Column {
2759
- static get instance() {
2760
- return this._instance ??= new BooleanColumn(internalSchemaConfig);
2761
- }
2762
- constructor(schema) {
2763
- super(schema, schema.boolean());
2764
- this.dataType = "bool";
2765
- this.operators = Operators.boolean;
2766
- this.data.alias = "boolean";
2767
- this.data.parseItem = parseItem;
2768
- }
2769
- toCode(ctx, key) {
2770
- return columnCode(this, ctx, key, "boolean()");
2771
- }
2772
- };
2773
- const parseItem = (input) => input[0] === "t";
2774
2772
  var SimpleRawSQL = class extends RawSql {
2775
2773
  makeSQL() {
2776
2774
  return this._sql;
@@ -3407,29 +3405,6 @@ var QueryHooks = class {
3407
3405
  }
3408
3406
  };
3409
3407
  /**
3410
- * generic utility to add a parser to the query object
3411
- * @param query - the query object, it will be mutated
3412
- * @param key - the name of the column in the data loaded by the query
3413
- * @param parser - function to process the value of the column with.
3414
- */
3415
- const setParserToQuery = (query, key, parser) => {
3416
- if (parser) if (query.parsers) query.parsers[key] = parser;
3417
- else query.parsers = { [key]: parser };
3418
- else if (query.parsers) delete query.parsers[key];
3419
- };
3420
- const getQueryParsers = (q, hookSelect) => {
3421
- if (hookSelect) {
3422
- const parsers = { ...q.q.parsers };
3423
- const { defaultParsers } = q.q;
3424
- if (defaultParsers) for (const [key, value] of hookSelect) {
3425
- const parser = defaultParsers[key];
3426
- if (parser) parsers[value.as || key] = parser;
3427
- }
3428
- return parsers;
3429
- }
3430
- return q.q.select ? q.q.parsers : q.q.defaultParsers;
3431
- };
3432
- /**
3433
3408
  * In snake case mode, or when columns have custom names,
3434
3409
  * use this method to exchange a db column name to its runtime key.
3435
3410
  */
@@ -4480,7 +4455,7 @@ const requirePrimaryKeys = (q, message) => {
4480
4455
  };
4481
4456
  const collectPrimaryKeys = (q) => {
4482
4457
  const primaryKeys = [];
4483
- const { shape } = q.q;
4458
+ const { shape } = q;
4484
4459
  for (const key in shape) if (shape[key].data.primaryKey) primaryKeys.push(key);
4485
4460
  const pkey = q.internal.tableData.primaryKey;
4486
4461
  if (pkey) primaryKeys.push(...pkey.columns);
@@ -4722,7 +4697,7 @@ const then = async (q, adapter, state, beforeHooks, afterHooks, afterSaveHooks,
4722
4697
  }
4723
4698
  const { tableHook, cteHooks } = sql;
4724
4699
  const { returnType = "all" } = query;
4725
- const tempReturnType = tableHook?.select || cteHooks?.hasSelect || returnType === "rows" && (q.q.batchParsers || adapter.driverAdapter.noFieldsForArrays) || checkIfNeedResultAllForMutativeQueriesSelectRelations(sql) ? "all" : returnType;
4700
+ const tempReturnType = tableHook?.select || cteHooks?.hasSelect || q.q.batchParsers || adapter.driverAdapter.noFieldsForArrays || checkIfNeedResultAllForMutativeQueriesSelectRelations(sql) ? "all" : returnType;
4726
4701
  let result;
4727
4702
  let queryResult;
4728
4703
  let cteData;
@@ -4978,12 +4953,25 @@ const execQuery = (adapter, method, sql, startingSavepoint, releasingSavepoint,
4978
4953
  });
4979
4954
  };
4980
4955
  const handleResult = (q, returnType, result, sql, isSubQuery) => {
4981
- const parsers = getQueryParsers(q, sql.tableHook?.select);
4956
+ let parsers = getQueryParsers(q, sql.tableHook?.select);
4982
4957
  switch (returnType) {
4983
4958
  case "all": {
4984
4959
  if (q.q.throwOnNotFound && result.rows.length === 0) throw new NotFoundError(q);
4985
4960
  const { rows } = result;
4986
- if (parsers) for (const row of rows) parseRecord(parsers, row);
4961
+ if (q.q.returnType === "value" || q.q.returnType === "valueOrThrow") {
4962
+ if (!rows.length) if (!q.q.select) return rows;
4963
+ else {
4964
+ if (q.q.returnType === "valueOrThrow") throw new NotFoundError(q);
4965
+ return [{ value: q.q.notFoundDefault }];
4966
+ }
4967
+ if (parsers) {
4968
+ const parser = getValueParser(parsers);
4969
+ if (parser) {
4970
+ const hookSelect = sql.tableHook?.select;
4971
+ for (const row of rows) for (const key in row) if (!hookSelect?.has(key)) row[key] = parser(row[key]);
4972
+ }
4973
+ }
4974
+ } else if (parsers) for (const row of rows) parseRecord(parsers, row);
4987
4975
  return rows;
4988
4976
  }
4989
4977
  case "one": {
@@ -5005,7 +4993,7 @@ const handleResult = (q, returnType, result, sql, isSubQuery) => {
5005
4993
  }
5006
4994
  case "pluck": {
5007
4995
  const { rows } = result;
5008
- parsePluck(parsers, isSubQuery, rows);
4996
+ parsePluck(q, parsers, isSubQuery, rows);
5009
4997
  return rows;
5010
4998
  }
5011
4999
  case "value": {
@@ -5042,14 +5030,26 @@ const parseRows = (parsers, fields, rows) => {
5042
5030
  if (parser) for (const row of rows) row[i] = parser(row[i]);
5043
5031
  }
5044
5032
  };
5045
- const parsePluck = (parsers, isSubQuery, rows) => {
5046
- const pluck = parsers?.pluck;
5047
- if (pluck) for (let i = 0; i < rows.length; i++) rows[i] = pluck(isSubQuery ? rows[i] : rows[i][0]);
5033
+ const parsePluck = (query, parsers, isSubQuery, rows) => {
5034
+ const valueToArray = query.q.getColumn?.data?.valueToArray;
5035
+ const parse = parsers?.pluck;
5036
+ if (parse) if (valueToArray) for (let i = 0; i < rows.length; i++) {
5037
+ const value = isSubQuery ? rows[i] : rows[i][0];
5038
+ rows[i] = value === null ? void 0 : value[0] === null ? null : parse(value[0]);
5039
+ }
5040
+ else for (let i = 0; i < rows.length; i++) {
5041
+ const value = isSubQuery ? rows[i] : rows[i][0];
5042
+ rows[i] = value === null ? value : parse(value);
5043
+ }
5044
+ else if (valueToArray) for (let i = 0; i < rows.length; i++) {
5045
+ const value = isSubQuery ? rows[i] : rows[i][0];
5046
+ rows[i] = value === null ? void 0 : value[0];
5047
+ }
5048
5048
  else if (!isSubQuery) for (let i = 0; i < rows.length; i++) rows[i] = rows[i][0];
5049
5049
  };
5050
5050
  const parseValue = (value, parsers) => {
5051
- const parser = parsers?.[getValueKey];
5052
- return parser ? parser(value) : value;
5051
+ const parse = getValueParser(parsers);
5052
+ return parse ? parse(value) : value;
5053
5053
  };
5054
5054
  const filterResult = (q, returnType, queryResult, result, tempColumns, hasAfterHook) => {
5055
5055
  if (returnType === "all") return filterAllResult(result, tempColumns, hasAfterHook);
@@ -5082,7 +5082,7 @@ const filterResult = (q, returnType, queryResult, result, tempColumns, hasAfterH
5082
5082
  }
5083
5083
  };
5084
5084
  const getFirstResultKey = (q, queryResult) => {
5085
- if (q.q.select) return queryResult.fields[0].name;
5085
+ if (q.q.select) return queryResult.fields[0] ? queryResult.fields[0].name : "value";
5086
5086
  else for (const key in q.q.selectedComputeds) return key;
5087
5087
  };
5088
5088
  const filterAllResult = (result, tempColumns, hasAfterHook) => {
@@ -5341,7 +5341,7 @@ function queryFrom(self, arg) {
5341
5341
  if (typeof arg === "string") {
5342
5342
  data.as ||= arg;
5343
5343
  const w = data.withShapes?.[arg];
5344
- data.shape = w?.shape ?? anyShape;
5344
+ data.selectShape = w?.shape ?? anyShape;
5345
5345
  data.runtimeComputeds = w?.computeds;
5346
5346
  const parsers = {};
5347
5347
  data.defaultParsers = parsers;
@@ -5352,7 +5352,7 @@ function queryFrom(self, arg) {
5352
5352
  arg = arg.slice(i + 1);
5353
5353
  } else if (w) data.schema = void 0;
5354
5354
  } else if (Array.isArray(arg)) {
5355
- const shape = { ...data.shape };
5355
+ const shape = { ...data.selectShape };
5356
5356
  const joinedParsers = {};
5357
5357
  for (const item of arg) if (typeof item === "string") {
5358
5358
  const w = data.withShapes[item];
@@ -5374,7 +5374,7 @@ function queryFrom(self, arg) {
5374
5374
  } else {
5375
5375
  const q = prepareSubQueryForSql(self, arg);
5376
5376
  data.as ||= q.q.as || q.table || "t";
5377
- data.shape = getShapeFromSelect(q, true);
5377
+ data.selectShape = getShapeFromSelect(q, true);
5378
5378
  data.defaultParsers = getQueryParsers(q);
5379
5379
  data.batchParsers = q.q.batchParsers;
5380
5380
  }
@@ -5571,7 +5571,7 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, shape, whereExists,
5571
5571
  const j = joinTo.qb.baseQuery.clone();
5572
5572
  j.table = first;
5573
5573
  j.q = {
5574
- shape: w.shape,
5574
+ selectShape: w.shape,
5575
5575
  runtimeComputeds: w.computeds,
5576
5576
  adapter: joinToQ.adapter,
5577
5577
  handleResult: joinToQ.handleResult,
@@ -5653,7 +5653,7 @@ const makeJoinQueryBuilder = (joinedQuery, joinedShapes, joinTo, shape) => {
5653
5653
  q.q.joinedShapes = joinedShapes;
5654
5654
  q.q.joinTo = joinTo;
5655
5655
  if (q.q.scopes) q.q.scopes = void 0;
5656
- if (shape) q.q.shape = shape;
5656
+ if (shape) q.q.selectShape = shape;
5657
5657
  return q;
5658
5658
  };
5659
5659
  const isRelationQuery = (q) => "joinQuery" in q;
@@ -6480,7 +6480,7 @@ const _chain = (fromQuery, toQuery, rel) => {
6480
6480
  }];
6481
6481
  _applyRelationAliases(self, q);
6482
6482
  q.joinedShapes = {
6483
- [getQueryAs(self)]: self.q.shape,
6483
+ [getQueryAs(self)]: self.q.selectShape,
6484
6484
  ...self.q.joinedShapes
6485
6485
  };
6486
6486
  rel.modifyRelatedQuery?.(query)?.(self);
@@ -6517,131 +6517,78 @@ const resolveSubQueryCallback = (q, cb) => {
6517
6517
  _setSubQueryAliases(arg);
6518
6518
  return cb(arg);
6519
6519
  };
6520
- /**
6521
- * Acts as {@link simpleExistingColumnToSQL} except that the column is optional and will return quoted key if no column.
6522
- */
6523
- function simpleColumnToSQL(ctx, key, column, quotedAs) {
6524
- if (!column) return `"${key}"`;
6525
- const { data } = column;
6526
- return data.computed ? `(${data.computed.toSQL(ctx, quotedAs)})` : `${quotedAs ? `${quotedAs}.` : ""}"${data.name || key}"`;
6527
- }
6528
- function simpleExistingColumnToSQL(ctx, key, column, quotedAs) {
6529
- const { data } = column;
6530
- return data.computed ? `(${data.computed.toSQL(ctx, quotedAs)})` : `${quotedAs ? `${quotedAs}.` : ""}"${data.name || key}"`;
6531
- }
6532
- const columnToSql = (ctx, data, shape, column, quotedAs, select) => {
6533
- let index = column.indexOf(".");
6534
- if (index === -1) {
6535
- const joinAs = data.valuesJoinedAs?.[column];
6536
- if (joinAs) {
6537
- column = joinAs + "." + column;
6538
- index = joinAs.length;
6520
+ function simpleColumnToSQL(ctx, queryData, shape, key, column, quotedAs, select, as, jsonList, useSelectList, skipSelectSql, skipValueToArray) {
6521
+ let sql;
6522
+ let dontAlias;
6523
+ if (useSelectList && queryData.select) {
6524
+ for (const s of queryData.select) if (typeof s === "object" && "selectAs" in s) {
6525
+ if (key in s.selectAs) {
6526
+ dontAlias = true;
6527
+ sql = simpleColumnToSQL(ctx, queryData, shape, key, shape[key], void 0, void 0, void 0, void 0, void 0, void 0, true);
6528
+ break;
6529
+ }
6539
6530
  }
6540
6531
  }
6541
- if (index !== -1) return columnWithDotToSql(ctx, data, shape, column, index, quotedAs, select);
6542
- return simpleColumnToSQL(ctx, column, shape[column], quotedAs);
6543
- };
6544
- const selectedColumnToSql = (ctx, data, shape, column, quotedAs) => {
6545
- const index = column.indexOf(".");
6546
- return index !== -1 ? selectedColumnWithDotToSql(ctx, data, shape, column, index, quotedAs) : selectedSimpleColumnToSql(ctx, column, shape[column], quotedAs);
6547
- };
6548
- const selectedSimpleColumnToSql = (ctx, key, column, quotedAs) => {
6549
- if (!column) return `"${key}"`;
6550
- const { data } = column;
6551
- return data.selectSql ? `(${data.selectSql.toSQL(ctx, quotedAs)})` : `${quotedAs ? `${quotedAs}.` : ""}"${data.name || key}"`;
6552
- };
6553
- /**
6554
- * in a case when ordering or grouping by a column which was selected as expression:
6555
- * ```ts
6556
- * table.select({ x: (q) => q.sum('x') }).group('x').order('x')
6557
- * ```
6558
- * the column must not be prefixed with a table name.
6559
- */
6560
- const maybeSelectedColumnToSql = (ctx, data, column, quotedAs) => {
6561
- const index = column.indexOf(".");
6562
- if (index !== -1) return columnWithDotToSql(ctx, data, data.shape, column, index, quotedAs);
6563
- else {
6564
- if (data.joinedShapes?.[column]) return `"${column}"."${column}"`;
6565
- if (data.select) {
6566
- for (const s of data.select) if (typeof s === "object" && "selectAs" in s) {
6567
- if (column in s.selectAs) return simpleColumnToSQL(ctx, column, data.shape[column]);
6532
+ if (!sql) if (!column) {
6533
+ dontAlias = key === as;
6534
+ sql = `${quotedAs ? `${quotedAs}.` : ""}"${key}"`;
6535
+ } else {
6536
+ if (jsonList && as) jsonList[as] = column && getSelectedColumnData(column);
6537
+ const { data } = column;
6538
+ if (select && data.selectSql && !skipSelectSql) sql = `(${data.selectSql.toSQL(ctx, quotedAs)})`;
6539
+ else if (data.computed) sql = `(${data.computed.toSQL(ctx, quotedAs)})`;
6540
+ else {
6541
+ const name = data.name || key;
6542
+ dontAlias = name === as;
6543
+ if (!select) {
6544
+ const joinAs = !select && queryData.valuesJoinedAs?.[key];
6545
+ if (joinAs) quotedAs = `"${joinAs}"`;
6568
6546
  }
6547
+ sql = `${quotedAs ? `${quotedAs}.` : ""}"${name}"`;
6569
6548
  }
6570
- return simpleColumnToSQL(ctx, column, data.shape[column], quotedAs);
6571
- }
6572
- };
6573
- const columnWithDotToSql = (ctx, data, shape, column, index, quotedAs, select) => {
6574
- const table = column.slice(0, index);
6575
- const key = column.slice(index + 1);
6576
- if (key === "*") {
6577
- const shape = data.joinedShapes?.[table];
6578
- return shape ? select ? makeRowToJson(ctx, table, shape, true) : `"${table}".*` : column;
6579
- }
6580
- const tableName = _getQueryAliasOrName(data, table);
6581
- const quoted = `"${table}"`;
6582
- const col = quoted === quotedAs ? shape[key] : data.joinedShapes?.[tableName]?.[key];
6583
- if (col) {
6584
- if (col.data.name) return `"${tableName}"."${col.data.name}"`;
6585
- if (col.data.computed) return `(${col.data.computed.toSQL(ctx, quoted)})`;
6586
- return `"${tableName}"."${key}"`;
6587
- }
6588
- return `"${tableName}"."${key}"`;
6589
- };
6590
- const selectedColumnWithDotToSql = (ctx, data, shape, column, index, quotedAs) => {
6591
- const table = column.slice(0, index);
6592
- const key = column.slice(index + 1);
6593
- if (key === "*") {
6594
- const shape = data.joinedShapes?.[table];
6595
- return shape ? makeRowToJson(ctx, table, shape, true) : column;
6596
- }
6597
- const tableName = _getQueryAliasOrName(data, table);
6598
- const quoted = `"${table}"`;
6599
- const col = quoted === quotedAs ? shape[key] : data.joinedShapes?.[tableName]?.[key];
6600
- if (col) {
6601
- if (col.data.selectSql) return `(${col.data.selectSql.toSQL(ctx, quoted)})`;
6602
- if (col.data.name) return `"${tableName}"."${col.data.name}"`;
6603
6549
  }
6604
- return `"${tableName}"."${key}"`;
6605
- };
6606
- const columnToSqlWithAs = (ctx, data, column, as, quotedAs, select, jsonList) => {
6607
- const index = column.indexOf(".");
6608
- return index !== -1 ? tableColumnToSqlWithAs(ctx, data, column, column.slice(0, index), column.slice(index + 1), as, quotedAs, select, jsonList) : ownColumnToSqlWithAs(ctx, data, column, as, quotedAs, select, jsonList);
6609
- };
6610
- const tableColumnToSqlWithAs = (ctx, data, column, table, key, as, quotedAs, select, jsonList) => {
6550
+ if (!select && !useSelectList && column?.data.valueToArray && !column.data.skipValueToArray) sql += "[1]";
6551
+ else if (queryData.getColumn?.data.valueToArray && !skipValueToArray) sql = `array[${sql}]`;
6552
+ if (as && !dontAlias) sql = `${sql} "${as}"`;
6553
+ return sql;
6554
+ }
6555
+ const tableColumnToSql = (ctx, queryData, shape, table, key, quotedAs, select, as, jsonList, skipValueToArray) => {
6556
+ let sql;
6557
+ let dontAlias;
6611
6558
  if (key === "*") {
6612
- if (jsonList) jsonList[as] = void 0;
6613
- const shape = data.joinedShapes?.[table];
6614
- if (shape) {
6615
- if (select) return makeRowToJson(ctx, table, shape, true) + ` "${as}"`;
6616
- return `"${table}"."${table}" "${as}"`;
6559
+ if (jsonList && as) jsonList[as] = void 0;
6560
+ const shape = queryData.joinedShapes?.[table];
6561
+ if (shape) sql = select ? makeRowToJson(ctx, table, shape, true) : `"${table}".*`;
6562
+ else {
6563
+ sql = `"${table}"."${key}"`;
6564
+ dontAlias = true;
6617
6565
  }
6618
- return column;
6619
- }
6620
- const tableName = _getQueryAliasOrName(data, table);
6621
- const quoted = `"${table}"`;
6622
- const col = quoted === quotedAs ? data.shape[key] : data.joinedShapes?.[tableName][key];
6623
- if (jsonList) jsonList[as] = col && getSelectedColumnData(col);
6624
- if (col) {
6625
- if (col.data.selectSql) return `(${col.data.selectSql.toSQL(ctx, quoted)}) "${as}"`;
6626
- if (col.data.name && col.data.name !== key) return `"${tableName}"."${col.data.name}" "${as}"`;
6566
+ } else {
6567
+ const tableName = _getQueryAliasOrName(queryData, table);
6568
+ const quoted = `"${table}"`;
6569
+ const col = quoted === quotedAs ? shape[key] : queryData.joinedShapes?.[tableName]?.[key];
6570
+ if (jsonList && as) jsonList[as] = col && getSelectedColumnData(col);
6571
+ if (col?.data.selectSql) sql = `(${col.data.selectSql.toSQL(ctx, quoted)})`;
6572
+ else if (col?.data.name) sql = `"${tableName}"."${col.data.name}"`;
6573
+ else if (col?.data.computed) sql = `(${col.data.computed.toSQL(ctx, quoted)})`;
6574
+ else {
6575
+ sql = `"${tableName}"."${key}"`;
6576
+ dontAlias = key === as;
6577
+ }
6578
+ if (!select && col?.data.valueToArray && !col.data.skipValueToArray) sql += "[1]";
6579
+ else if (queryData.getColumn?.data.valueToArray && !skipValueToArray) sql = `array[${sql}]`;
6627
6580
  }
6628
- return `"${tableName}"."${key}"${key === as ? "" : ` "${as}"`}`;
6581
+ if (as && !dontAlias) sql = `${sql} "${as}"`;
6582
+ return sql;
6629
6583
  };
6630
- const ownColumnToSqlWithAs = (ctx, data, column, as, quotedAs, select, jsonList) => {
6631
- if (!select && data.joinedShapes?.[column]) {
6632
- if (jsonList) jsonList[as] = void 0;
6633
- return `"${column}"."${column}" "${as}"`;
6634
- }
6635
- const col = data.shape[column];
6636
- if (jsonList) jsonList[as] = col && getSelectedColumnData(col);
6637
- if (col) {
6638
- if (col.data.selectSql) return `(${col.data.selectSql.toSQL(ctx, quotedAs)}) "${as}"`;
6639
- if (col.data.name && col.data.name !== column) return `${quotedAs ? `${quotedAs}.` : ""}"${col.data.name}"${col.data.name === as ? "" : ` "${as}"`}`;
6640
- }
6641
- return `${quotedAs ? `${quotedAs}.` : ""}"${column}"${column === as ? "" : ` "${as}"`}`;
6584
+ const columnToSqlNotSelect = (ctx, data, shape, column, quotedAs, useSelectList) => columnToSql(ctx, data, shape, column, quotedAs, void 0, void 0, void 0, useSelectList, true);
6585
+ const columnToSql = (ctx, data, shape, column, quotedAs, select, as, jsonList, useSelectList, skipValueToArray) => {
6586
+ let index = column.indexOf(".");
6587
+ if (index !== -1) return tableColumnToSql(ctx, data, shape, column.slice(0, index), column.slice(index + 1), quotedAs, select, as, jsonList, skipValueToArray);
6588
+ return simpleColumnToSQL(ctx, data, shape, column, shape[column], quotedAs, select, as, jsonList, useSelectList, void 0, skipValueToArray);
6642
6589
  };
6643
- const rawOrColumnToSql = (ctx, data, expr, quotedAs, shape = data.shape, select) => {
6644
- return typeof expr === "string" ? columnToSql(ctx, data, shape, expr, quotedAs, select) : expr.toSQL(ctx, quotedAs);
6590
+ const rawOrColumnToSql = (ctx, data, shape, expr, quotedAs, select, skipValueToArray) => {
6591
+ return typeof expr === "string" ? columnToSql(ctx, data, shape, expr, quotedAs, select, void 0, void 0, void 0, skipValueToArray) : expr.toSQL(ctx, quotedAs);
6645
6592
  };
6646
6593
  const processJoinItem = (ctx, table, query, args, quotedAs) => {
6647
6594
  let target;
@@ -6701,7 +6648,7 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
6701
6648
  joinedShapes: {
6702
6649
  ...query.joinedShapes,
6703
6650
  ...q.q.joinedShapes,
6704
- [table.q.as || table.table]: table.q.shape
6651
+ [table.q.as || table.table]: table.q.selectShape
6705
6652
  }
6706
6653
  }, joinAs);
6707
6654
  if (whereSql) if (on) on += ` AND ${whereSql}`;
@@ -6750,17 +6697,17 @@ const getConditionsFor3Or4LengthItem = (ctx, query, target, quotedAs, args, join
6750
6697
  const [leftColumn, opOrRightColumn, maybeRightColumn] = args;
6751
6698
  const op = maybeRightColumn ? opOrRightColumn : "=";
6752
6699
  const rightColumn = maybeRightColumn ? maybeRightColumn : opOrRightColumn;
6753
- return `${rawOrColumnToSql(ctx, query, leftColumn, target, joinShape)} ${op} ${rawOrColumnToSql(ctx, query, rightColumn, quotedAs, query.shape)}`;
6700
+ return `${rawOrColumnToSql(ctx, query, joinShape, leftColumn, target)} ${op} ${rawOrColumnToSql(ctx, query, query.selectShape, rightColumn, quotedAs)}`;
6754
6701
  };
6755
6702
  const getObjectOrRawConditions = (ctx, query, data, quotedAs, joinAs, joinShape) => {
6756
6703
  if (data === true) return "true";
6757
6704
  else if (isExpression(data)) return data.toSQL(ctx, quotedAs);
6758
6705
  else {
6759
6706
  const pairs = [];
6760
- const shape = query.shape;
6707
+ const shape = query.selectShape;
6761
6708
  for (const key in data) {
6762
6709
  const value = data[key];
6763
- pairs.push(`${columnToSql(ctx, query, joinShape, key, joinAs)} = ${rawOrColumnToSql(ctx, query, value, quotedAs, shape)}`);
6710
+ pairs.push(`${columnToSqlNotSelect(ctx, query, joinShape, key, joinAs)} = ${rawOrColumnToSql(ctx, query, shape, value, quotedAs)}`);
6764
6711
  }
6765
6712
  return pairs.join(", ");
6766
6713
  }
@@ -6792,11 +6739,11 @@ var SelectItemExpression = class extends Expression {
6792
6739
  }
6793
6740
  makeSQL(ctx, quotedAs) {
6794
6741
  const q = this.q;
6795
- return typeof this.item === "string" ? this.item === "*" ? selectAllSql(q, quotedAs, void 0, ctx).join(", ") : selectedColumnToSql(ctx, q, q.shape, this.item, quotedAs) : this.item.toSQL(ctx, quotedAs);
6742
+ return typeof this.item === "string" ? this.item === "*" ? selectAllSql(q, quotedAs, void 0, ctx).join(", ") : columnToSql(ctx, q, q.selectShape, this.item, quotedAs, true, void 0, void 0, void 0, true) : this.item.toSQL(ctx, quotedAs);
6796
6743
  }
6797
6744
  };
6798
6745
  const _getSelectableColumn = (q, arg) => {
6799
- let type = q.q.shape[arg];
6746
+ let type = q.q.selectShape[arg];
6800
6747
  if (!type) {
6801
6748
  const index = arg.indexOf(".");
6802
6749
  if (index !== -1) {
@@ -6813,30 +6760,17 @@ const _get = (query, returnType, arg) => {
6813
6760
  const q = query.q;
6814
6761
  if (q.returning) q.returning = void 0;
6815
6762
  q.returnType = returnType;
6816
- let type;
6817
6763
  let value = arg;
6818
- if (typeof value === "function") {
6819
- const item = processSelectAsArg(query, getQueryAs(query), "value", value);
6820
- if (item !== false) value = item;
6821
- }
6822
- if (typeof value === "string") {
6823
- const joinedAs = q.valuesJoinedAs?.[value];
6824
- type = joinedAs ? q.joinedShapes?.[joinedAs]?.value : _getSelectableColumn(query, value);
6825
- q.getColumn = type;
6826
- const selected = setParserForSelectedString(query, joinedAs ? joinedAs + "." + value : value, getQueryAs(query), getValueKey);
6827
- q.select = selected ? [q.expr = new SelectItemExpression(query, selected, type)] : void 0;
6828
- } else if (isExpression(value)) {
6829
- type = value.result.value;
6830
- q.getColumn = type;
6831
- addParserForRawExpression(query, getValueKey, value);
6832
- q.select = [q.expr = value];
6833
- } else {
6834
- const selected = value;
6835
- q.getColumn = selected.q.getColumn;
6836
- if (q.getColumn) addColumnParserToQuery(q, getValueKey, q.getColumn);
6837
- q.select = selected ? [{ selectAs: { value: selected } }] : void 0;
6764
+ const selectAs = {};
6765
+ let column;
6766
+ const selected = processSelectAsArg(query, selectAs, getQueryAs(query), "v", value, void 0, returnType);
6767
+ if (selected !== false) {
6768
+ q.getColumn = column = selected;
6769
+ value = selectAs.v || value;
6838
6770
  }
6839
- return setQueryOperators(query, type?.operators || Operators.any);
6771
+ if (typeof value === "string") value = selectAs.v && new SelectItemExpression(query, selectAs.v, column);
6772
+ q.select = isExpression(value) ? [q.expr = value] : value ? [{ selectAs: { v: value } }] : void 0;
6773
+ return setQueryOperators(query, column?.operators || Operators.any);
6840
6774
  };
6841
6775
  function _queryGet(self, arg) {
6842
6776
  return _get(self, "valueOrThrow", arg);
@@ -7085,13 +7019,13 @@ const selectToSqlList = (ctx, table, query, quotedAs, hookSelect = query.hookSel
7085
7019
  (selected ??= {})[key] = `"${tableName}"`;
7086
7020
  (selectedAs ??= {})[key] = key;
7087
7021
  }
7088
- sql = tableColumnToSqlWithAs(ctx, table.q, item, tableName, key, key === "*" ? tableName : key, quotedAs, true, jsonList);
7022
+ sql = tableColumnToSql(ctx, query, query.selectShape, tableName, key, quotedAs, true, key === "*" ? tableName : key, jsonList);
7089
7023
  } else {
7090
7024
  if (hookSelect?.get(item)) {
7091
7025
  (selected ??= {})[item] = quotedAs;
7092
7026
  (selectedAs ??= {})[item] = item;
7093
7027
  }
7094
- sql = ownColumnToSqlWithAs(ctx, table.q, item, item, quotedAs, true, jsonList);
7028
+ sql = simpleColumnToSQL(ctx, query, query.selectShape, item, query.selectShape[item], quotedAs, true, item, jsonList);
7095
7029
  }
7096
7030
  }
7097
7031
  list.push(sql);
@@ -7103,7 +7037,9 @@ const selectToSqlList = (ctx, table, query, quotedAs, hookSelect = query.hookSel
7103
7037
  if (hookSelect) (selected ??= {})[as] = true;
7104
7038
  const value = obj[as];
7105
7039
  if (typeof value === "object") if (isExpression(value)) {
7106
- list.push(`${value.toSQL(ctx, quotedAs)} "${as}"`);
7040
+ let sql = value.toSQL(ctx, quotedAs);
7041
+ if (value.q.getColumn?.data.valueToArray) sql = `array[${sql}]`;
7042
+ list.push(`${sql} "${as}"`);
7107
7043
  if (jsonList) jsonList[as] = value.result.value;
7108
7044
  aliases?.push(as);
7109
7045
  } else if (delayedRelationSelect && isRelationQuery(value)) setMutativeQueriesSelectRelationsSqlState(delayedRelationSelect, as, value);
@@ -7113,13 +7049,14 @@ const selectToSqlList = (ctx, table, query, quotedAs, hookSelect = query.hookSel
7113
7049
  }
7114
7050
  else if (value) {
7115
7051
  if (hookSelect) (selectedAs ??= {})[value] = as;
7116
- list.push(columnToSqlWithAs(ctx, table.q, value, as, quotedAs, true, jsonList));
7052
+ list.push(columnToSql(ctx, table.q, table.q.selectShape, value, quotedAs, true, as, jsonList));
7117
7053
  aliases?.push(as);
7118
7054
  }
7119
7055
  }
7120
7056
  } else {
7121
7057
  ctx.selectedCount++;
7122
- const sql = item.toSQL(ctx, quotedAs);
7058
+ let sql = item.toSQL(ctx, quotedAs);
7059
+ if (item.q.getColumn?.data.valueToArray) sql = `array[${sql}]`;
7123
7060
  if (hookSelect && item instanceof SelectItemExpression && typeof item.item === "string" && item.item !== "*") {
7124
7061
  const i = item.item.indexOf(".");
7125
7062
  let key;
@@ -7127,7 +7064,7 @@ const selectToSqlList = (ctx, table, query, quotedAs, hookSelect = query.hookSel
7127
7064
  if (item.item.slice(0, i) === table.table) key = item.item.slice(i + 1);
7128
7065
  } else key = item.item;
7129
7066
  if (key) {
7130
- const column = item.q.shape[key];
7067
+ const column = item.q.selectShape[key];
7131
7068
  (selectedAs ??= {})[key] = column?.data.name || key;
7132
7069
  }
7133
7070
  }
@@ -7149,12 +7086,12 @@ const selectToSqlList = (ctx, table, query, quotedAs, hookSelect = query.hookSel
7149
7086
  quotedTable = `"${tableName}"`;
7150
7087
  columnName = select.slice(index + 1);
7151
7088
  col = table.q.joinedShapes?.[tableName]?.[columnName];
7152
- sql = selectedColumnToSql(ctx, table.q, table.q.shape, select, void 0);
7089
+ sql = columnToSql(ctx, table.q, table.shape, select, void 0, true, void 0, void 0, void 0, true);
7153
7090
  } else {
7154
7091
  quotedTable = quotedAs;
7155
7092
  columnName = select;
7156
- col = query.shape[select];
7157
- sql = selectedColumnToSql(ctx, table.q, query.shape, select, quotedAs);
7093
+ col = table.shape[select];
7094
+ sql = columnToSql(ctx, table.q, table.shape, select, quotedAs, true, void 0, void 0, void 0, true);
7158
7095
  }
7159
7096
  } else {
7160
7097
  columnName = column;
@@ -7199,15 +7136,15 @@ const internalSelectAllSql = (ctx, query, quotedAs, jsonList) => {
7199
7136
  jsonList[key] = getSelectedColumnData(column);
7200
7137
  }
7201
7138
  let columnsCount;
7202
- if (query.shape !== anyShape) {
7139
+ if (query.selectShape !== anyShape) {
7203
7140
  columnsCount = 0;
7204
- for (const key in query.shape) if (!query.shape[key].data.explicitSelect) columnsCount++;
7141
+ for (const key in query.selectShape) if (!query.selectShape[key].data.explicitSelect) columnsCount++;
7205
7142
  ctx.selectedCount += columnsCount;
7206
7143
  }
7207
7144
  return selectAllSql(query, quotedAs, columnsCount, ctx);
7208
7145
  };
7209
7146
  const selectAllSql = (q, quotedAs, columnsCount, ctx) => {
7210
- return q.join?.length || q.updateFrom || q.updateMany ? q.selectAllColumns?.map((item) => selectAllColumnToSql(item, ctx, quotedAs, true)) || (isEmptySelect(q.shape, columnsCount) ? [] : [`${quotedAs}.*`]) : q.selectAllColumns ? q.selectAllColumns.map((item) => selectAllColumnToSql(item, ctx, quotedAs)) : isEmptySelect(q.shape, columnsCount) ? [] : ["*"];
7147
+ return q.join?.length || q.updateFrom || q.updateMany ? q.selectAllColumns?.map((item) => selectAllColumnToSql(item, ctx, quotedAs, true)) || (isEmptySelect(q.selectShape, columnsCount) ? [] : [`${quotedAs}.*`]) : q.selectAllColumns ? q.selectAllColumns.map((item) => selectAllColumnToSql(item, ctx, quotedAs)) : isEmptySelect(q.selectShape, columnsCount) ? [] : ["*"];
7211
7148
  };
7212
7149
  const selectAllColumnToSql = (item, ctx, quotedAs, prefix) => {
7213
7150
  if (typeof item !== "string") return item(ctx, quotedAs);
@@ -7383,9 +7320,9 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
7383
7320
  ands.push(`NOT ${processAnds(arr, ctx, table, query, quotedAs, true)}`);
7384
7321
  } else if (key === "ON") if (Array.isArray(value)) {
7385
7322
  const item = value;
7386
- const leftColumn = columnToSql(ctx, query, query.shape, item[0], quotedAs);
7323
+ const leftColumn = columnToSqlNotSelect(ctx, query, query.selectShape, item[0], quotedAs);
7387
7324
  const leftPath = item[1];
7388
- const rightColumn = columnToSql(ctx, query, query.shape, item[2], quotedAs);
7325
+ const rightColumn = columnToSqlNotSelect(ctx, query, query.selectShape, item[2], quotedAs);
7389
7326
  const rightPath = item[3];
7390
7327
  ands.push(`jsonb_path_query_first(${leftColumn}, ${addValue(ctx.values, leftPath)}) = jsonb_path_query_first(${rightColumn}, ${addValue(ctx.values, rightPath)})`);
7391
7328
  } else {
@@ -7394,7 +7331,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
7394
7331
  const q = item.useOuterAliases ? {
7395
7332
  joinedShapes: query.joinedShapes,
7396
7333
  aliases: _getQueryOuterAliases(query),
7397
- shape: query.shape
7334
+ selectShape: query.selectShape
7398
7335
  } : query;
7399
7336
  ands.push(`${onColumnToSql(ctx, q, joinAs, item.from)} ${item.op || "="} ${onColumnToSql(ctx, q, joinAs, item.to)}`);
7400
7337
  }
@@ -7418,31 +7355,26 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
7418
7355
  ands.push(`${search.vectorSQL} @@ "${search.as}"`);
7419
7356
  } else if (typeof value === "object" && value && !(value instanceof Date) && !Array.isArray(value)) whereExprOrQuery(ctx, ands, query, key, value, quotedAs);
7420
7357
  else {
7421
- const column = columnToSql(ctx, query, query.shape, key, quotedAs);
7358
+ const column = columnToSqlNotSelect(ctx, query, query.selectShape, key, quotedAs);
7422
7359
  ands.push(`${column} ${value === null ? "IS NULL" : `= ${addValue(ctx.values, value)}`}`);
7423
7360
  }
7424
7361
  }
7425
7362
  };
7426
7363
  const whereExprOrQuery = (ctx, ands, query, key, value, quotedAs) => {
7427
- if (isExpression(value)) ands.push(`${columnToSql(ctx, query, query.shape, key, quotedAs)} = ${value.toSQL(ctx, quotedAs)}`);
7364
+ if (isExpression(value)) ands.push(`${columnToSqlNotSelect(ctx, query, query.selectShape, key, quotedAs)} = ${value.toSQL(ctx, quotedAs)}`);
7428
7365
  else {
7429
- let column = query.shape[key];
7430
- let quotedColumn;
7431
- if (column) quotedColumn = simpleExistingColumnToSQL(ctx, key, column, quotedAs);
7432
- else if (!column) {
7366
+ let column = query.selectShape[key];
7367
+ if (!column) {
7433
7368
  const index = key.indexOf(".");
7434
- if (index !== -1) {
7369
+ if (index === -1) column = query.joinedShapes?.[key]?.value;
7370
+ else if (index !== -1) {
7435
7371
  const table = key.slice(0, index);
7436
- const quoted = `"${table}"`;
7437
7372
  const name = key.slice(index + 1);
7438
- column = quotedAs === quoted ? query.shape[name] : query.joinedShapes?.[table]?.[name];
7439
- quotedColumn = simpleColumnToSQL(ctx, name, column, quoted);
7440
- } else {
7441
- column = query.joinedShapes?.[key]?.value;
7442
- quotedColumn = `"${key}"."${key}"`;
7373
+ column = quotedAs === `"${table}"` ? query.selectShape[name] : query.joinedShapes?.[table]?.[name];
7443
7374
  }
7444
- if (!column || !quotedColumn) throw new Error(`Unknown column ${key} provided to condition`);
7445
7375
  }
7376
+ if (!column) throw new Error(`Unknown column ${key} provided to condition`);
7377
+ const quotedColumn = columnToSqlNotSelect(ctx, query, query.selectShape, key, quotedAs);
7446
7378
  if (value instanceof ctx.qb.constructor) {
7447
7379
  const subQuerySql = moveMutativeQueryToCte(ctx, value);
7448
7380
  ands.push(`${quotedColumn} = (${subQuerySql})`);
@@ -7454,7 +7386,7 @@ const whereExprOrQuery = (ctx, ands, query, key, value, quotedAs) => {
7454
7386
  }
7455
7387
  }
7456
7388
  };
7457
- const onColumnToSql = (ctx, query, joinAs, column) => columnToSql(ctx, query, query.shape, column, joinAs);
7389
+ const onColumnToSql = (ctx, query, joinAs, column) => columnToSqlNotSelect(ctx, query, query.selectShape, column, joinAs);
7458
7390
  const getJoinItemSource = (joinItem) => {
7459
7391
  return typeof joinItem === "string" ? joinItem : getQueryAs(joinItem);
7460
7392
  };
@@ -7466,13 +7398,14 @@ const pushIn = (ctx, query, ands, quotedAs, arg) => {
7466
7398
  value = `(${value})`;
7467
7399
  } else if (isExpression(arg.values)) value = arg.values.toSQL(ctx, quotedAs);
7468
7400
  else value = `(${moveMutativeQueryToCte(ctx, arg.values)})`;
7469
- const columnsSql = arg.columns.map((column) => columnToSql(ctx, query, query.shape, column, quotedAs)).join(", ");
7401
+ const columnsSql = arg.columns.map((column) => columnToSqlNotSelect(ctx, query, query.selectShape, column, quotedAs)).join(", ");
7470
7402
  ands.push(`${multiple ? `(${columnsSql})` : columnsSql} IN ${value}`);
7471
7403
  };
7472
7404
  const MAX_BINDING_PARAMS = 65533;
7473
7405
  const makeInsertSql = (ctx, q, query, quotedAs, isSubSql) => {
7474
7406
  let { columns } = query;
7475
- const { shape, hookCreateSet } = query;
7407
+ const shape = q.shape;
7408
+ const { hookCreateSet } = query;
7476
7409
  const QueryClass = ctx.qb.constructor;
7477
7410
  let { insertFrom, queryColumnsCount, values } = query;
7478
7411
  let hookSetSql;
@@ -7509,7 +7442,7 @@ const makeInsertSql = (ctx, q, query, quotedAs, isSubSql) => {
7509
7442
  insertSql: `INSERT INTO ${quoteTableWithSchema(q)}${quotedColumns.length ? "(" + quotedColumns.join(", ") + ")" : ""}`
7510
7443
  };
7511
7444
  ctx.sql.push(null, null);
7512
- const hasOnConflictWhere = pushOnConflictSql(ctx, query, quotedAs, columns, quotedColumns, runtimeDefaultColumns);
7445
+ const hasOnConflictWhere = pushOnConflictSql(ctx, q, query, quotedAs, columns, quotedColumns, runtimeDefaultColumns);
7513
7446
  const upsert = query.type === "upsert";
7514
7447
  if (upsert || insertFrom && !isRelationQuery(q) || hasOnConflictWhere) pushWhereStatementSql(ctx, q, query, quotedAs);
7515
7448
  sqlState.relationSelectState = newMutativeQueriesSelectRelationsSqlState(q);
@@ -7576,9 +7509,9 @@ const makeInsertSql = (ctx, q, query, quotedAs, isSubSql) => {
7576
7509
  values: ctx.values
7577
7510
  };
7578
7511
  };
7579
- const pushOnConflictSql = (ctx, query, quotedAs, columns, quotedColumns, runtimeDefaultColumns) => {
7512
+ const pushOnConflictSql = (ctx, q, query, quotedAs, columns, quotedColumns, runtimeDefaultColumns) => {
7580
7513
  if (!query.onConflict) return false;
7581
- const { shape } = query;
7514
+ const shape = q.shape;
7582
7515
  ctx.sql.push("ON CONFLICT");
7583
7516
  const { target } = query.onConflict;
7584
7517
  if (target) if (typeof target === "string") ctx.sql.push(`("${shape[target]?.data.name || target}")`);
@@ -7791,7 +7724,7 @@ const pushUpdateSqlWithoutValuesJoinedAs = (ctx, query, q, quotedAs, isSubSql) =
7791
7724
  let updateManyValuesSql;
7792
7725
  if (q.updateMany) {
7793
7726
  for (const key of q.updateMany.primaryKeys) usedSetKeys.add(key);
7794
- updateManyValuesSql = makeUpdateManyValuesSql(ctx, query, q, q.updateMany, set, usedSetKeys, quotedAs);
7727
+ updateManyValuesSql = makeUpdateManyValuesSql(ctx, query, q.updateMany, set, usedSetKeys, quotedAs);
7795
7728
  }
7796
7729
  if (!set.length) pushSelectForEmptySet(ctx, query, q, quotedAs, from, isSubSql, updateManyValuesSql, relationSelectState);
7797
7730
  else {
@@ -7866,7 +7799,7 @@ const processData = (ctx, query, set, data, hookSet, usedSetKeys, quotedAs) => {
7866
7799
  };
7867
7800
  const applySet = (ctx, query, set, item, skipColumns, usedSetKeys, quotedAs) => {
7868
7801
  const QueryClass = ctx.qb.constructor;
7869
- const shape = query.q.shape;
7802
+ const shape = query.shape;
7870
7803
  for (const key in item) {
7871
7804
  if (usedSetKeys.has(key)) continue;
7872
7805
  usedSetKeys.add(key);
@@ -7882,12 +7815,12 @@ const processValue = (ctx, query, QueryClass, key, value, quotedAs) => {
7882
7815
  const subQuery = value;
7883
7816
  if (subQuery.q.subQuery === 1) return selectToSql(ctx, query, subQuery.q, quotedAs);
7884
7817
  return `(${moveMutativeQueryToCte(ctx, subQuery)})`;
7885
- } else if ("op" in value && "arg" in value) return `"${query.q.shape[key].data.name || key}" ${value.op} ${addValue(ctx.values, value.arg)}`;
7818
+ } else if ("op" in value && "arg" in value) return `"${query.shape[key].data.name || key}" ${value.op} ${addValue(ctx.values, value.arg)}`;
7886
7819
  }
7887
7820
  return addValue(ctx.values, value);
7888
7821
  };
7889
- const makeUpdateManyValuesSql = (ctx, query, q, updateMany, set, usedSetKeys, quotedAs) => {
7890
- const { shape } = q;
7822
+ const makeUpdateManyValuesSql = (ctx, query, updateMany, set, usedSetKeys, quotedAs) => {
7823
+ const shape = query.shape;
7891
7824
  const keysSet = /* @__PURE__ */ new Set();
7892
7825
  const valueRows = [];
7893
7826
  const quotedColumnNames = [];
@@ -7996,13 +7929,13 @@ const addOrder = (ctx, data, column, quotedAs, dir) => {
7996
7929
  const order = dir || (!search.order || search.order === true ? emptyObject : search.order);
7997
7930
  return `${order.coverDensity ? "ts_rank_cd" : "ts_rank"}(${order.weights ? `${addValue(ctx.values, `{${order.weights}}`)}, ` : ""}${search.vectorSQL}, "${column}"${order.normalization !== void 0 ? `, ${addValue(ctx.values, order.normalization)}` : ""}) ${order.dir || "DESC"}`;
7998
7931
  }
7999
- return `${maybeSelectedColumnToSql(ctx, data, column, quotedAs)} ${dir || "ASC"}`;
7932
+ return `${columnToSqlNotSelect(ctx, data, data.selectShape, column, quotedAs, true)} ${dir || "ASC"}`;
8000
7933
  };
8001
7934
  const windowToSql = (ctx, data, window, quotedAs) => {
8002
7935
  if (typeof window === "string") return `"${window}"`;
8003
7936
  if (isExpression(window)) return `(${window.toSQL(ctx, quotedAs)})`;
8004
7937
  const sql = [];
8005
- if (window.partitionBy) sql.push(`PARTITION BY ${Array.isArray(window.partitionBy) ? window.partitionBy.map((partitionBy) => rawOrColumnToSql(ctx, data, partitionBy, quotedAs)).join(", ") : rawOrColumnToSql(ctx, data, window.partitionBy, quotedAs)}`);
7938
+ if (window.partitionBy) sql.push(`PARTITION BY ${Array.isArray(window.partitionBy) ? window.partitionBy.map((partitionBy) => rawOrColumnToSql(ctx, data, data.selectShape, partitionBy, quotedAs, void 0, true)).join(", ") : rawOrColumnToSql(ctx, data, data.selectShape, window.partitionBy, quotedAs, void 0, true)}`);
8006
7939
  if (window.order) sql.push(`ORDER BY ${orderByToSql(ctx, data, window.order, quotedAs)}`);
8007
7940
  return `(${sql.join(" ")})`;
8008
7941
  };
@@ -8023,12 +7956,6 @@ var FnExpression = class extends Expression {
8023
7956
  this.result = { value };
8024
7957
  this.q = query.q;
8025
7958
  this.q.expr = this;
8026
- Object.assign(query, value.operators);
8027
- query.q.returnType = "valueOrThrow";
8028
- query.q.returnsOne = true;
8029
- query.q.getColumn = value;
8030
- query.q.select = [this];
8031
- addColumnParserToQuery(query.q, getValueKey, value);
8032
7959
  }
8033
7960
  makeSQL(ctx, quotedAs) {
8034
7961
  const sql = [`${this.fn}(`];
@@ -8057,7 +7984,7 @@ var FnExpression = class extends Expression {
8057
7984
  const whereSql = whereToSql(ctx, this.query, {
8058
7985
  and: options.filter ? [options.filter] : void 0,
8059
7986
  or: options.filterOr?.map((item) => [item]),
8060
- shape: q.shape,
7987
+ selectShape: q.selectShape,
8061
7988
  joinedShapes: q.joinedShapes
8062
7989
  }, quotedAs);
8063
7990
  if (whereSql) sql.push(` FILTER (WHERE ${whereSql})`);
@@ -8068,16 +7995,22 @@ var FnExpression = class extends Expression {
8068
7995
  };
8069
7996
  const fnArgToSql = (ctx, data, arg, quotedAs) => {
8070
7997
  if (typeof arg === "string") {
8071
- if (arg.endsWith(".*") || data.valuesJoinedAs?.[arg]) return columnToSql(ctx, data, data.shape, arg, quotedAs);
8072
- return selectedColumnToSql(ctx, data, data.shape, arg, quotedAs);
7998
+ if (arg.endsWith(".*") || data.valuesJoinedAs?.[arg]) return columnToSql(ctx, data, data.selectShape, arg, quotedAs, void 0, void 0, void 0, void 0, true);
7999
+ return columnToSql(ctx, data, data.selectShape, arg, quotedAs, true, void 0, void 0, void 0, true);
8073
8000
  }
8074
8001
  return arg.toSQL(ctx, quotedAs);
8075
8002
  };
8076
8003
  function makeFnExpression(self, type, fn, args, options) {
8077
8004
  const q = extendQuery(self, type.operators);
8078
8005
  q.baseQuery.type = ExpressionTypeMethod.prototype.type;
8079
- new FnExpression(q, fn, args, options, type);
8006
+ q.q.select = [new FnExpression(q, fn, args, options, type)];
8007
+ q.q.getColumn = type;
8008
+ Object.assign(q, type.operators);
8009
+ setValueParserToQuery(q.q, type);
8010
+ q.q.returnType = "valueOrThrow";
8011
+ q.q.returnsOne = true;
8080
8012
  q.q.transform = void 0;
8013
+ q.q.batchParsers = void 0;
8081
8014
  return q;
8082
8015
  }
8083
8016
  const isSelectingCount = (q) => {
@@ -8086,17 +8019,14 @@ const isSelectingCount = (q) => {
8086
8019
  };
8087
8020
  const intNullable = new IntegerColumn(internalSchemaConfig).nullable().parse(parseInt);
8088
8021
  const floatNullable = new RealColumn(internalSchemaConfig).nullable().parse(parseFloat);
8089
- const booleanNullable = BooleanColumn.instance.nullable();
8022
+ const booleanNullable = BooleanColumn.instanceSkipValueToArray.nullable();
8090
8023
  const textNullable = TextColumn.instance.nullable();
8091
8024
  const jsonTextNullable = JSONTextColumn.instance.nullable();
8092
8025
  const xmlNullable = XMLColumn.instance.nullable();
8093
8026
  const stringAsNumberNullable = new NumberAsStringBaseColumn(internalSchemaConfig).nullable();
8027
+ intNullable.data.skipValueToArray = floatNullable.data.skipValueToArray = textNullable.data.skipValueToArray = jsonTextNullable.data.skipValueToArray = xmlNullable.data.skipValueToArray = stringAsNumberNullable.data.skipValueToArray = true;
8094
8028
  const numericResultColumn = (q, arg) => {
8095
- const query = q;
8096
- let column = (typeof arg === "string" ? _getSelectableColumn(query, arg) : arg.result.value) instanceof NumberBaseColumn ? floatNullable : stringAsNumberNullable;
8097
- const parse = typeof arg === "string" && query.q.parsers?.[arg];
8098
- if (parse) column = column.parse(parse);
8099
- return column;
8029
+ return (typeof arg === "string" ? _getSelectableColumn(q, arg) : arg.result.value) instanceof NumberBaseColumn ? floatNullable : stringAsNumberNullable;
8100
8030
  };
8101
8031
  var AggregateMethods = class {
8102
8032
  /**
@@ -8112,6 +8042,7 @@ var AggregateMethods = class {
8112
8042
  const q = _queryGetOptional(_clone(this), new RawSql("true"));
8113
8043
  q.q.notFoundDefault = false;
8114
8044
  q.q.coalesceValue = new RawSql("false");
8045
+ q.q.getColumn = BooleanColumn.instanceSkipValueToArray;
8115
8046
  return q;
8116
8047
  }
8117
8048
  /**
@@ -8873,7 +8804,7 @@ const createSelect = (q) => {
8873
8804
  * @param createHandlers - collects column `create` functions per column having it, and collects row indexes having a value for this column
8874
8805
  */
8875
8806
  const processCreateItem = (q, item, rowIndex, ctx, encoders, createHandlers) => {
8876
- const { shape } = q.q;
8807
+ const shape = q.shape;
8877
8808
  for (const key in item) {
8878
8809
  const column = shape[key];
8879
8810
  if (!column) continue;
@@ -9424,7 +9355,7 @@ var OnConflictQueryBuilder = class {
9424
9355
  const pushDistinctSql = (ctx, table, distinct, quotedAs) => {
9425
9356
  ctx.sql.push("DISTINCT");
9426
9357
  if (distinct.length) {
9427
- const columns = distinct?.map((item) => rawOrColumnToSql(ctx, table.q, item, quotedAs));
9358
+ const columns = distinct?.map((item) => rawOrColumnToSql(ctx, table.q, table.q.selectShape, item, quotedAs));
9428
9359
  ctx.sql.push(`ON (${columns?.join(", ") || ""})`);
9429
9360
  }
9430
9361
  };
@@ -9458,20 +9389,20 @@ const searchSourcesToSql = (ctx, data, sources, sql, quotedAs) => {
9458
9389
  return sql;
9459
9390
  };
9460
9391
  const getSearchLang = (ctx, data, source, quotedAs) => {
9461
- return source.langSQL ??= "languageColumn" in source ? columnToSql(ctx, data, data.shape, source.languageColumn, quotedAs) : isRawSQL(source.language) ? source.language.toSQL(ctx) : addValue(ctx.values, source.language || data.language || "english");
9392
+ return source.langSQL ??= "languageColumn" in source ? columnToSqlNotSelect(ctx, data, data.selectShape, source.languageColumn, quotedAs) : isRawSQL(source.language) ? source.language.toSQL(ctx) : addValue(ctx.values, source.language || data.language || "english");
9462
9393
  };
9463
9394
  const getSearchText = (ctx, data, source, quotedAs, forHeadline) => {
9464
9395
  let sql = source.textSQL;
9465
9396
  if (sql) return sql;
9466
- if ("in" in source) if (typeof source.in === "string") sql = columnToSql(ctx, data, data.shape, source.in, quotedAs);
9467
- else if (Array.isArray(source.in)) sql = `concat_ws(' ', ${source.in.map((column) => columnToSql(ctx, data, data.shape, column, quotedAs)).join(", ")})`;
9397
+ if ("in" in source) if (typeof source.in === "string") sql = columnToSqlNotSelect(ctx, data, data.selectShape, source.in, quotedAs);
9398
+ else if (Array.isArray(source.in)) sql = `concat_ws(' ', ${source.in.map((column) => columnToSqlNotSelect(ctx, data, data.selectShape, column, quotedAs)).join(", ")})`;
9468
9399
  else {
9469
9400
  sql = [];
9470
- for (const key in source.in) sql.push(columnToSql(ctx, data, data.shape, key, quotedAs));
9401
+ for (const key in source.in) sql.push(columnToSqlNotSelect(ctx, data, data.selectShape, key, quotedAs));
9471
9402
  }
9472
9403
  else if ("vector" in source) {
9473
9404
  if (forHeadline) throw new Error("Cannot use a search based on a vector column for a search headline");
9474
- sql = columnToSql(ctx, data, data.shape, source.vector, quotedAs);
9405
+ sql = columnToSqlNotSelect(ctx, data, data.selectShape, source.vector, quotedAs);
9475
9406
  } else if (typeof source.text === "string") sql = addValue(ctx.values, source.text);
9476
9407
  else sql = source.text.toSQL(ctx, quotedAs);
9477
9408
  return source.textSQL = sql;
@@ -9687,7 +9618,7 @@ const toSql = (table, type, topCtx, isSubSql, cteName, calledByThen, dontAddTabl
9687
9618
  if (isExpression(item)) return item.toSQL(ctx, quotedAs);
9688
9619
  else {
9689
9620
  const i = aliases.indexOf(item);
9690
- return i !== -1 ? i + 1 : columnToSql(ctx, table.q, table.shape, item, quotedAs);
9621
+ return i !== -1 ? i + 1 : columnToSqlNotSelect(ctx, table.q, table.shape, item, quotedAs);
9691
9622
  }
9692
9623
  });
9693
9624
  sql.push(`GROUP BY ${group.join(", ")}`);
@@ -10109,19 +10040,11 @@ const _joinLateral = (self, type, joinQuery, as, innerJoinLateral) => {
10109
10040
  }
10110
10041
  if (!existingValue) {
10111
10042
  const joinedAs = getQueryAs(query);
10112
- setObjectValueImmutable(joinQuery.q, "joinedShapes", joinedAs, query.q.shape);
10043
+ setObjectValueImmutable(joinQuery.q, "joinedShapes", joinedAs, query.q.selectShape);
10113
10044
  }
10114
10045
  const shape = getShapeFromSelect(joinQuery, true);
10115
10046
  setObjectValueImmutable(query.q, "joinedShapes", joinAs, shape);
10116
- const parsers = getQueryParsers(joinQuery);
10117
- if (joinValue) {
10118
- setObjectValueImmutable(query.q, "valuesJoinedAs", joinAs, joinValueAs);
10119
- if (parsers && getValueKey in parsers) {
10120
- const parse = parsers[getValueKey];
10121
- setParserToQuery(query.q, joinAs, parse);
10122
- parsers[joinAs] = parse;
10123
- }
10124
- }
10047
+ if (joinValue) setObjectValueImmutable(query.q, "valuesJoinedAs", joinAs, joinValueAs);
10125
10048
  setObjectValueImmutable(query.q, "joinedParsers", joinValueAs || joinAs, getQueryParsers(joinQuery));
10126
10049
  if (joinQuery.q.batchParsers) setObjectValueImmutable(query.q, "joinedBatchParsers", joinAs, joinQuery.q.batchParsers);
10127
10050
  if (joinValueAs) {
@@ -10881,15 +10804,12 @@ var OnMethods = class {
10881
10804
  const setSelectRelation = (q) => {
10882
10805
  q.selectRelation = true;
10883
10806
  };
10884
- const addParserForRawExpression = (q, key, raw) => {
10885
- if (raw.result.value) addColumnParserToQuery(q.q, key, raw.result.value);
10886
- };
10887
10807
  const addParsersForSelectJoined = (q, arg, as = arg) => {
10888
10808
  const parsers = q.q.joinedParsers?.[arg];
10889
10809
  if (parsers) setParserToQuery(q.q, as, (row) => parseRecord(parsers, row));
10890
10810
  const batchParsers = q.q.joinedBatchParsers?.[arg];
10891
10811
  if (batchParsers) pushQueryArrayImmutable(q, "batchParsers", batchParsers.map((x) => ({
10892
- path: [as, ...x.path],
10812
+ path: [{ key: as }, ...x.path],
10893
10813
  fn: x.fn
10894
10814
  })));
10895
10815
  };
@@ -10897,19 +10817,24 @@ const addParserForSelectItem = (query, as, key, arg, columnAlias, joinQuery) =>
10897
10817
  if (typeof arg === "object") {
10898
10818
  const { q } = arg;
10899
10819
  if (q.batchParsers) pushQueryArrayImmutable(query, "batchParsers", q.batchParsers.map((bp) => ({
10900
- path: [key, ...bp.path],
10820
+ path: [{
10821
+ key,
10822
+ returnType: q.returnType
10823
+ }, ...bp.path],
10901
10824
  fn: bp.fn
10902
10825
  })));
10903
10826
  const parsers = isExpression(arg) ? void 0 : getQueryParsers(arg);
10904
10827
  if (parsers || q.hookSelect || q.transform || q.returnType === "oneOrThrow" || q.returnType === "valueOrThrow" || q.returnType === "one" || q.returnType === "value") pushQueryValueImmutable(query, "batchParsers", {
10905
- path: [key],
10828
+ path: [{
10829
+ key,
10830
+ returnType: q.returnType
10831
+ }],
10906
10832
  fn: (path, queryResult) => {
10907
10833
  const { rows } = queryResult;
10908
10834
  const originalReturnType = q.returnType || "all";
10909
10835
  let returnType = originalReturnType;
10910
10836
  const { hookSelect } = q;
10911
10837
  const batches = [];
10912
- const last = path.length;
10913
10838
  if (returnType === "value" || returnType === "valueOrThrow") {
10914
10839
  if (hookSelect) batches.push = (item) => {
10915
10840
  if (!(key in item)) returnType = returnType === "value" ? "one" : "oneOrThrow";
@@ -10917,7 +10842,7 @@ const addParserForSelectItem = (query, as, key, arg, columnAlias, joinQuery) =>
10917
10842
  return batches.push(item);
10918
10843
  };
10919
10844
  }
10920
- collectNestedSelectBatches(batches, rows, path, last);
10845
+ collectNestedSelectBatches(batches, rows, path);
10921
10846
  switch (returnType) {
10922
10847
  case "all":
10923
10848
  if (parsers) for (const { data } of batches) for (const one of data) parseRecord(parsers, one);
@@ -10942,16 +10867,28 @@ const addParserForSelectItem = (query, as, key, arg, columnAlias, joinQuery) =>
10942
10867
  }
10943
10868
  case "value":
10944
10869
  case "valueOrThrow": {
10945
- const notNullable = !q.getColumn?.data.isNullable;
10946
- const parse = parsers?.[getValueKey];
10947
- if (parse) if (returnType === "value") for (const item of batches) item.parent[item.key] = item.data = item.data === null ? q.notFoundDefault : parse(item.data);
10870
+ const data = q.getColumn?.data;
10871
+ const notNullable = !data?.isNullable;
10872
+ const valueToArray = data?.valueToArray;
10873
+ const parse = getValueParser(parsers);
10874
+ if (parse) if (returnType === "value") if (valueToArray) for (const item of batches) item.parent[item.key] = item.data = item.data ? item.data[0] === null ? null : parse(item.data[0]) : q.notFoundDefault;
10875
+ else for (const item of batches) item.parent[item.key] = item.data = item.data === null ? q.notFoundDefault : parse(item.data);
10876
+ else if (valueToArray) for (const item of batches) {
10877
+ if (!item.data) throw new NotFoundError(arg);
10878
+ item.parent[item.key] = item.data = item.data[0] === null ? null : parse(item.data[0]);
10879
+ }
10948
10880
  else for (const item of batches) {
10949
10881
  if (notNullable && item.data === null) throw new NotFoundError(arg);
10950
10882
  item.parent[item.key] = item.data = parse(item.data);
10951
10883
  }
10952
10884
  else if (returnType === "value") {
10953
- for (const item of batches) if (item.data === null) item.parent[item.key] = item.data = q.notFoundDefault;
10954
- } else if (notNullable) {
10885
+ if (valueToArray) for (const item of batches) item.parent[item.key] = item.data = item.data ? item.data[0] : q.notFoundDefault;
10886
+ else for (const item of batches) if (item.data === void 0) item.parent[item.key] = item.data = q.notFoundDefault;
10887
+ } else if (valueToArray) for (const item of batches) {
10888
+ if (!item.data) throw new NotFoundError(arg);
10889
+ item.parent[item.key] = item.data = item.data[0];
10890
+ }
10891
+ else if (notNullable) {
10955
10892
  for (const { data } of batches) if (data === null) throw new NotFoundError(arg);
10956
10893
  }
10957
10894
  if (hookSelect) for (const batch of batches) batch.data = [batch.data];
@@ -10989,59 +10926,52 @@ const addParserForSelectItem = (query, as, key, arg, columnAlias, joinQuery) =>
10989
10926
  }
10990
10927
  return arg;
10991
10928
  }
10992
- return setParserForSelectedString(query, arg, as, key, columnAlias);
10929
+ const joinedAs = query.q.valuesJoinedAs?.[arg];
10930
+ return setParserForSelectedString(query, joinedAs ? joinedAs + "." + arg : arg, as, key, columnAlias);
10993
10931
  };
10994
- const collectNestedSelectBatches = (batches, rows, path, last) => {
10995
- const stack = rows.map((row) => ({
10996
- data: row,
10997
- parent: row,
10998
- i: 0,
10999
- key: path[0]
11000
- }));
11001
- while (stack.length > 0) {
11002
- const item = stack.pop();
11003
- const { i } = item;
11004
- if (i === last) {
11005
- batches.push(item);
11006
- continue;
11007
- }
11008
- const { data } = item;
11009
- const key = path[i];
11010
- if (Array.isArray(data)) for (let key = 0; key < data.length; key++) stack.push({
11011
- data: data[key],
11012
- parent: data,
11013
- key,
11014
- i
11015
- });
11016
- else if (data && typeof data === "object") stack.push({
11017
- data: data[key],
11018
- parent: data,
11019
- key,
11020
- i: i + 1
11021
- });
10932
+ const collectNestedSelectBatches = (batches, rows, path) => {
10933
+ const last = path.length - 1;
10934
+ const { key, returnType } = path[0];
10935
+ for (const row of rows) processNestedSelectPathEntry(batches, path, key, returnType, 0, last, row);
10936
+ };
10937
+ const processNestedSelectPathEntry = (batches, path, thisKey, thisReturnType, i, last, parent) => {
10938
+ const data = parent[thisKey];
10939
+ if (i === last) batches.push({
10940
+ data,
10941
+ parent,
10942
+ key: thisKey
10943
+ });
10944
+ else {
10945
+ const { key, returnType } = path[++i];
10946
+ if (!thisReturnType || thisReturnType === "all") for (const row of data) processNestedSelectPathEntry(batches, path, key, returnType, i, last, row);
10947
+ else processNestedSelectPathEntry(batches, path, key, returnType, i, last, data);
11022
10948
  }
11023
10949
  };
11024
10950
  const emptyArrSQL = new RawSql("'[]'");
11025
10951
  const processSelectArg = (q, as, arg, columnAs) => {
11026
- if (typeof arg === "string") return setParserForSelectedString(q, arg, as, columnAs);
10952
+ const query = q;
10953
+ if (typeof arg === "string") return setParserForSelectedString(query, arg, as, columnAs);
11027
10954
  const selectAs = {};
10955
+ const selectShape = query.q.selectShape = { ...query.q.selectShape };
11028
10956
  for (const key in arg) {
11029
- const item = processSelectAsArg(q, as, key, arg[key]);
11030
- if (item === false) return false;
11031
- selectAs[key] = item;
10957
+ const item = processSelectAsArg(q, selectAs, as, key, arg[key], key);
10958
+ if (item) selectShape[key] = item;
10959
+ else if (item === false) return false;
11032
10960
  }
11033
10961
  return { selectAs };
11034
10962
  };
11035
- const processSelectAsArg = (q, as, key, arg) => {
10963
+ const processSelectAsArg = (q, selectAs, as, key, arg, columnAlias, outerReturnType) => {
11036
10964
  const query = q;
11037
10965
  let value = arg;
11038
10966
  let joinQuery;
10967
+ let column;
11039
10968
  if (typeof value === "function") {
11040
10969
  value = resolveSubQueryCallback(q, value);
11041
10970
  if (isQueryNone(value)) {
11042
10971
  if (value.q.innerJoinLateral) return false;
11043
10972
  }
11044
- if (!isExpression(value)) {
10973
+ if (isExpression(value)) column = value.result.value;
10974
+ else {
11045
10975
  if (isRelationQuery(value) && value.q.subQuery !== 1) {
11046
10976
  joinQuery = true;
11047
10977
  setSelectRelation(query.q);
@@ -11062,10 +10992,27 @@ const processSelectAsArg = (q, as, key, arg) => {
11062
10992
  const as = _joinLateral(q, innerJoinLateral || query.q.returnType === "valueOrThrow" ? "JOIN" : "LEFT JOIN", subQuery, key, innerJoinLateral && returnType !== "one" && returnType !== "oneOrThrow");
11063
10993
  if (as) value.q.joinedForSelect = _copyQueryAliasToQuery(value, q, as);
11064
10994
  }
10995
+ if (value.q.getColumn?.data.skipValueToArray) value.q.notFoundDefault ??= null;
10996
+ else if (!value.q.type && (value.q.returnType === "value" || value.q.returnType === "valueOrThrow")) {
10997
+ const column = Object.create(value.q.getColumn || UnknownColumn.instance);
10998
+ column.data = {
10999
+ ...column.data,
11000
+ name: void 0,
11001
+ valueToArray: true
11002
+ };
11003
+ value.q.getColumn = column;
11004
+ if (value.q.expr) value.q.expr.q.getColumn = column;
11005
+ }
11006
+ if (outerReturnType === "value" && value.q.returnType === "valueOrThrow") value.q.returnType = "value";
11007
+ column = value.q.getColumn;
11065
11008
  value = prepareSubQueryForSql(q, value);
11066
11009
  }
11067
- }
11068
- return addParserForSelectItem(query, as, key, value, key, joinQuery);
11010
+ } else if (typeof value === "string") {
11011
+ const joinedAs = query.q.valuesJoinedAs?.[value];
11012
+ column = joinedAs ? query.q.joinedShapes?.[joinedAs]?.value : _getSelectableColumn(query, value);
11013
+ } else column = value.result.value;
11014
+ selectAs[key] = addParserForSelectItem(query, as, key, value, columnAlias, joinQuery);
11015
+ return column;
11069
11016
  };
11070
11017
  const setParserForSelectedString = (query, arg, as, columnAs, columnAlias) => {
11071
11018
  const { q } = query;
@@ -11083,7 +11030,7 @@ const setParserForSelectedString = (query, arg, as, columnAs, columnAlias) => {
11083
11030
  const batchParsers = q.joinedBatchParsers?.[table];
11084
11031
  if (batchParsers) {
11085
11032
  let cloned = false;
11086
- for (const bp of batchParsers) if (bp.path[0] === column) {
11033
+ for (const bp of batchParsers) if (bp.path[0].key === column) {
11087
11034
  if (!cloned) {
11088
11035
  q.batchParsers = [...q.batchParsers || []];
11089
11036
  cloned = true;
@@ -11121,7 +11068,7 @@ const selectColumn = (query, q, key, columnAs, columnAlias) => {
11121
11068
  };
11122
11069
  const getShapeFromSelect = (q, isSubQuery) => {
11123
11070
  const query = q.q;
11124
- const { shape } = query;
11071
+ const { selectShape: shape } = query;
11125
11072
  let select;
11126
11073
  if (query.selectedComputeds) {
11127
11074
  select = query.select ? [...query.select] : [];
@@ -11598,14 +11545,14 @@ var RefExpression = class extends Expression {
11598
11545
  makeSQL(ctx) {
11599
11546
  const q = this.q;
11600
11547
  const as = q.as || this.table;
11601
- return columnToSql(ctx, q, q.shape, this.ref, as && `"${as}"`);
11548
+ return columnToSqlNotSelect(ctx, q, q.selectShape, this.ref, as && `"${as}"`);
11602
11549
  }
11603
11550
  };
11604
11551
  const _queryUpdateMany = (self, primaryKeys, data, strict) => {
11605
11552
  const query = self;
11606
11553
  throwIfReadOnly(query);
11607
11554
  const { q } = query;
11608
- const { shape } = q;
11555
+ const shape = query.shape;
11609
11556
  q.type = "update";
11610
11557
  setUpdateReturning(q);
11611
11558
  if (!data.length) return _queryNone(query);
@@ -11661,7 +11608,7 @@ const _queryUpdate = (updateSelf, arg) => {
11661
11608
  q.type = "update";
11662
11609
  const set = { ...arg };
11663
11610
  pushQueryValueImmutable(query, "updateData", set);
11664
- const { shape } = q;
11611
+ const shape = query.shape;
11665
11612
  let selectQuery;
11666
11613
  for (const key in arg) {
11667
11614
  const item = shape[key];
@@ -12334,7 +12281,7 @@ var ColumnRefExpression = class extends Expression {
12334
12281
  Object.assign(this, value.operators);
12335
12282
  }
12336
12283
  makeSQL(ctx, quotedAs) {
12337
- return simpleExistingColumnToSQL(ctx, this.name, this.result.value, quotedAs);
12284
+ return simpleColumnToSQL(ctx, emptyObject, emptyObject, this.name, this.result.value, quotedAs, void 0, void 0, void 0, void 0, true);
12338
12285
  }
12339
12286
  };
12340
12287
  var OrExpression = class extends Expression {
@@ -12421,16 +12368,16 @@ var QueryExpressions = class {
12421
12368
  */
12422
12369
  ref(arg) {
12423
12370
  const q = _clone(this);
12424
- const { shape } = q.q;
12371
+ const { selectShape } = q.q;
12425
12372
  let column;
12426
12373
  const index = arg.indexOf(".");
12427
12374
  if (index !== -1) {
12428
12375
  const as = q.q.as || q.table;
12429
12376
  const table = getFullColumnTable(q, arg, index, as);
12430
12377
  const col = arg.slice(index + 1);
12431
- if (table === as) column = shape[col];
12378
+ if (table === as) column = selectShape[col];
12432
12379
  else column = q.q.joinedShapes?.[table][col];
12433
- } else column = shape[arg];
12380
+ } else column = selectShape[arg];
12434
12381
  return new RefExpression(column || UnknownColumn.instance, q, arg);
12435
12382
  }
12436
12383
  val(value) {
@@ -12473,7 +12420,7 @@ var QueryExpressions = class {
12473
12420
  * @param options
12474
12421
  */
12475
12422
  fn(fn, args, options) {
12476
- return makeFnExpression(this, emptyObject, fn, args, options);
12423
+ return makeFnExpression(this, UnknownColumn.instance, fn, args, options);
12477
12424
  }
12478
12425
  or(...args) {
12479
12426
  return new OrExpression(args);
@@ -12486,7 +12433,7 @@ const _appendQueryOnUpsertCreate = (main, append, asFn) => {
12486
12433
  return pushQueryValueImmutable(pushQueryValueImmutable(main, "upsertCreateAppendQueries", prepareSubQueryForSql(main, append)), "upsertCreateAsFns", asFn);
12487
12434
  };
12488
12435
  const mergableObjects = new Set([
12489
- "shape",
12436
+ "selectShape",
12490
12437
  "withShapes",
12491
12438
  "defaultParsers",
12492
12439
  "parsers",
@@ -12690,7 +12637,7 @@ var Headline = class extends Expression {
12690
12637
  const { source, params } = this;
12691
12638
  const q = this.q;
12692
12639
  const lang = getSearchLang(ctx, q, source, quotedAs);
12693
- const text = params?.text ? params.text instanceof Expression ? params.text.toSQL(ctx, quotedAs) : columnToSql(ctx, q, q.shape, params.text, quotedAs) : getSearchText(ctx, q, source, quotedAs, true);
12640
+ const text = params?.text ? params.text instanceof Expression ? params.text.toSQL(ctx, quotedAs) : columnToSqlNotSelect(ctx, q, q.selectShape, params.text, quotedAs) : getSearchText(ctx, q, source, quotedAs, true);
12694
12641
  const options = params?.options ? `, ${params.options instanceof Expression ? params.options.toSQL(ctx, quotedAs) : addValue(ctx.values, params.options)}` : "";
12695
12642
  return `ts_headline(${lang}, ${text}, "${source.as}"${options})`;
12696
12643
  }
@@ -13016,10 +12963,12 @@ var QueryPluck = class {
13016
12963
  const q = _clone(this);
13017
12964
  q.q.returnType = "pluck";
13018
12965
  let selected;
13019
- if (typeof select === "function") {
13020
- const item = processSelectAsArg(q, q.q.as || q.table, "pluck", select);
13021
- if (item !== false) selected = isExpression(item) ? item : { selectAs: { pluck: item } };
13022
- } else selected = addParserForSelectItem(q, q.q.as || q.table, "pluck", select);
12966
+ const selectAs = {};
12967
+ const item = processSelectAsArg(q, selectAs, q.q.as || q.table, "pluck", select, void 0, "value");
12968
+ if (item !== false) {
12969
+ q.q.getColumn = item;
12970
+ selected = typeof selectAs.pluck === "object" && !isExpression(selectAs.pluck) ? { selectAs } : selectAs.pluck;
12971
+ }
13023
12972
  q.q.select = selected ? [selected] : void 0;
13024
12973
  return q;
13025
12974
  }
@@ -13957,7 +13906,7 @@ var Db = class extends QueryMethods {
13957
13906
  };
13958
13907
  this.q = {
13959
13908
  adapter: adapterNotInTransaction,
13960
- shape,
13909
+ selectShape: shape,
13961
13910
  handleResult,
13962
13911
  logger,
13963
13912
  log: logParamToLogObject(logger, options.log),
@@ -14295,7 +14244,7 @@ const makeColumnInfoSql = (query, column) => {
14295
14244
  const values = [];
14296
14245
  const schema = getQuerySchema(query);
14297
14246
  let text = `SELECT * FROM information_schema.columns WHERE table_name = ${addValue(values, query.table)} AND table_catalog = current_database() AND table_schema = ${schema ? addValue(values, schema) : "current_schema()"}`;
14298
- if (column) text += ` AND column_name = ${addValue(values, query.q.shape[column]?.data.name || column)}`;
14247
+ if (column) text += ` AND column_name = ${addValue(values, query.shape[column]?.data.name || column)}`;
14299
14248
  return {
14300
14249
  text,
14301
14250
  values
@@ -14351,7 +14300,7 @@ const makeCopySql = (table, copy) => {
14351
14300
  const ctx = newToSqlCtx(table);
14352
14301
  const { q } = table;
14353
14302
  const quotedAs = `"${q.as || table.table}"`;
14354
- const columns = copy.columns ? `(${copy.columns.map((item) => `"${q.shape[item]?.data.name || item}"`).join(", ")})` : "";
14303
+ const columns = copy.columns ? `(${copy.columns.map((item) => `"${table.shape[item]?.data.name || item}"`).join(", ")})` : "";
14355
14304
  const target = "from" in copy ? copy.from : copy.to;
14356
14305
  const quotedTable = quoteTableWithSchema(table);
14357
14306
  ctx.sql.push(`COPY ${quotedTable}${columns} ${"from" in copy ? "FROM" : "TO"} ${typeof target === "string" ? escapeString(target) : `PROGRAM ${escapeString(target.program)}`}`);