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.js CHANGED
@@ -1704,6 +1704,44 @@ const columnCode = (type, ctx, key, code) => {
1704
1704
  if (data.modifyQuery && !ctx.migration) addCode(code, `.modifyQuery(${data.modifyQuery.toString()})`);
1705
1705
  return code.length === 1 && typeof code[0] === "string" ? code[0] : code;
1706
1706
  };
1707
+ /**
1708
+ * generic utility to add a parser to the query object
1709
+ * @param query - the query object, it will be mutated
1710
+ * @param key - the name of the column in the data loaded by the query
1711
+ * @param parser - function to process the value of the column with.
1712
+ */
1713
+ const setParserToQuery = (query, key, parser) => {
1714
+ if (parser) if (query.parsers) query.parsers[key] = parser;
1715
+ else query.parsers = { [key]: parser };
1716
+ else if (query.parsers) delete query.parsers[key];
1717
+ };
1718
+ const getQueryParsers = (q, hookSelect) => {
1719
+ if (hookSelect) {
1720
+ const parsers = { ...q.q.parsers };
1721
+ const { defaultParsers } = q.q;
1722
+ if (defaultParsers) for (const [key, value] of hookSelect) {
1723
+ const parser = defaultParsers[key];
1724
+ if (parser) parsers[value.as || key] = parser;
1725
+ }
1726
+ return parsers;
1727
+ }
1728
+ return q.q.select ? q.q.parsers : q.q.defaultParsers;
1729
+ };
1730
+ const addColumnParserToQuery = (q, key, column) => {
1731
+ if (column._parse) setObjectValueImmutable(q, "parsers", key, column._parse);
1732
+ };
1733
+ const setValueParserToQuery = (q, column) => {
1734
+ addColumnParserToQuery(q, "v", column);
1735
+ };
1736
+ const getValueParser = (parsers) => {
1737
+ return parsers?.v;
1738
+ };
1739
+ const setValueParser = (q, parser) => {
1740
+ setObjectValueImmutable(q, "parsers", "v", parser);
1741
+ };
1742
+ const addParserForRawExpression = (q, key, raw) => {
1743
+ if (raw.result.value) addColumnParserToQuery(q.q, key, raw.result.value);
1744
+ };
1707
1745
  var CustomTypeColumn = class extends Column {
1708
1746
  constructor(schema, typeName, typeSchema, extension) {
1709
1747
  super(schema, schema.unknown(), schema.unknown(), schema.unknown());
@@ -1751,9 +1789,6 @@ var EnumColumn = class extends Column {
1751
1789
  return `"${index === -1 ? name : `${name.slice(0, index)}"."${name.slice(index + 1)}`}"`;
1752
1790
  }
1753
1791
  };
1754
- const addColumnParserToQuery = (q, key, column) => {
1755
- if (column._parse) setObjectValueImmutable(q, "parsers", key, column._parse);
1756
- };
1757
1792
  const setColumnDefaultParse = (column, parse) => {
1758
1793
  column.data.parse = parse;
1759
1794
  column._parse = (input) => input === null ? null : parse(input);
@@ -1795,174 +1830,6 @@ const setColumnEncode = (column, fn, inputSchema) => {
1795
1830
  const getColumnBaseType = (column, domainsMap, type) => {
1796
1831
  return column instanceof EnumColumn ? "text" : column instanceof DomainColumn ? domainsMap[column.dataType]?.dataType : type;
1797
1832
  };
1798
- const getValueKey = Symbol("get");
1799
- let moveMutativeQueryToCte$1;
1800
- const setMoveMutativeQueryToCte = (fn) => {
1801
- moveMutativeQueryToCte$1 = fn;
1802
- };
1803
- let prepareSubQueryForSql$1;
1804
- const setPrepareSubQueryForSql = (fn) => {
1805
- prepareSubQueryForSql$1 = fn;
1806
- };
1807
- let dbClass;
1808
- const setDb = (db) => {
1809
- dbClass = db;
1810
- };
1811
- function setQueryOperators(query, operators) {
1812
- const q = query.q;
1813
- if (q.operators !== operators) {
1814
- q.operators = operators;
1815
- Object.assign(query, operators);
1816
- }
1817
- return query;
1818
- }
1819
- /**
1820
- * Makes operator function that has `_op` property.
1821
- *
1822
- * @param _op - function to turn the operator call into SQL.
1823
- */
1824
- const make = (_op) => {
1825
- return Object.assign(function(value) {
1826
- const { q } = this;
1827
- const val = prepareOpArg(this, value);
1828
- (q.chain ??= []).push(_op, val || value);
1829
- if (q.parsers?.[getValueKey]) setObjectValueImmutable(q, "parsers", getValueKey, void 0);
1830
- return setQueryOperators(this, boolean);
1831
- }, { _op });
1832
- };
1833
- const makeVarArg = (_op) => {
1834
- return Object.assign(function(...args) {
1835
- const { q } = this;
1836
- args.forEach((arg, i) => {
1837
- const val = prepareOpArg(this, arg);
1838
- if (val) args[i] = val;
1839
- });
1840
- (q.chain ??= []).push(_op, args);
1841
- if (q.parsers?.[getValueKey]) setObjectValueImmutable(q, "parsers", getValueKey, void 0);
1842
- return setQueryOperators(this, boolean);
1843
- }, { _op });
1844
- };
1845
- const prepareOpArg = (q, arg) => {
1846
- return arg instanceof dbClass ? prepareSubQueryForSql$1(q, arg) : void 0;
1847
- };
1848
- const quoteValue = (arg, ctx, quotedAs, IN) => {
1849
- if (arg && typeof arg === "object") {
1850
- if (IN && isIterable(arg)) return `(${(Array.isArray(arg) ? arg : [...arg]).map((value) => addValue(ctx.values, value)).join(", ")})`;
1851
- if (isExpression(arg)) return arg.toSQL(ctx, quotedAs);
1852
- if ("toSQL" in arg) return `(${moveMutativeQueryToCte$1(ctx, arg)})`;
1853
- if (!(arg instanceof Date) && !Array.isArray(arg)) arg = JSON.stringify(arg);
1854
- }
1855
- return addValue(ctx.values, arg);
1856
- };
1857
- const quoteLikeValue = (arg, ctx, quotedAs, jsonArray) => {
1858
- if (arg && typeof arg === "object") {
1859
- if (!jsonArray && Array.isArray(arg)) return `(${arg.map((value) => addValue(ctx.values, value)).join(", ")})`;
1860
- if (isExpression(arg)) return arg.toSQL(ctx, quotedAs);
1861
- if ("toSQL" in arg) return `replace(replace((${moveMutativeQueryToCte$1(ctx, arg)}), '%', '\\\\%'), '_', '\\\\_')`;
1862
- }
1863
- return addValue(ctx.values, arg.replace(/[%_]/g, "\\$&"));
1864
- };
1865
- const base = {
1866
- equals: make((key, value, ctx, quotedAs) => value === null ? `${key} IS NULL` : `${key} = ${quoteValue(value, ctx, quotedAs)}`),
1867
- not: make((key, value, ctx, quotedAs) => value === null ? `${key} IS NOT NULL` : `${key} <> ${quoteValue(value, ctx, quotedAs)}`),
1868
- in: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "false" : `${key} IN ${quoteValue(value, ctx, quotedAs, true)}`),
1869
- notIn: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "true" : `NOT ${key} IN ${quoteValue(value, ctx, quotedAs, true)}`)
1870
- };
1871
- const ord = {
1872
- ...base,
1873
- lt: make((key, value, ctx, quotedAs) => `${key} < ${quoteValue(value, ctx, quotedAs)}`),
1874
- lte: make((key, value, ctx, quotedAs) => `${key} <= ${quoteValue(value, ctx, quotedAs)}`),
1875
- gt: make((key, value, ctx, quotedAs) => `${key} > ${quoteValue(value, ctx, quotedAs)}`),
1876
- gte: make((key, value, ctx, quotedAs) => `${key} >= ${quoteValue(value, ctx, quotedAs)}`),
1877
- between: make((key, [from, to], ctx, quotedAs) => `${key} BETWEEN ${quoteValue(from, ctx, quotedAs)} AND ${quoteValue(to, ctx, quotedAs)}`)
1878
- };
1879
- const boolean = {
1880
- ...ord,
1881
- and: make((key, value, ctx, quotedAs) => `${key} AND ${value.q.expr.toSQL(ctx, quotedAs)}`),
1882
- or: make((key, value, ctx, quotedAs) => `(${key}) OR (${value.q.expr.toSQL(ctx, quotedAs)})`)
1883
- };
1884
- const text = {
1885
- ...base,
1886
- contains: make((key, value, ctx, quotedAs) => `${key} ILIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
1887
- containsSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
1888
- startsWith: make((key, value, ctx, quotedAs) => `${key} ILIKE ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
1889
- startsWithSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
1890
- endsWith: make((key, value, ctx, quotedAs) => `${key} ILIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)}`),
1891
- endsWithSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)}`)
1892
- };
1893
- const ordinalText = {
1894
- ...ord,
1895
- ...text
1896
- };
1897
- const encodeJsonPath = (ctx, path) => addValue(ctx.values, `{${Array.isArray(path) ? path.join(", ") : path}}`);
1898
- 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" : ""})`;
1899
- const shouldEncodeJson = (ctx) => ctx.q.adapter.driverAdapter.schemaConfig?.jsonEncodedByDriver === false;
1900
- const quoteJsonValue = (arg, ctx, quotedAs, IN) => {
1901
- if (arg && typeof arg === "object") {
1902
- if (IN && Array.isArray(arg)) return `(${arg.map((value) => shouldEncodeJson(ctx) ? addValue(ctx.values, JSON.stringify(value)) : addValue(ctx.values, value)).join(", ")})`;
1903
- if (Array.isArray(arg)) return shouldEncodeJson(ctx) ? addValue(ctx.values, JSON.stringify(arg)) : addValue(ctx.values, arg);
1904
- if (isExpression(arg)) return "to_jsonb(" + arg.toSQL(ctx, quotedAs) + ")";
1905
- if ("toSQL" in arg) return `to_jsonb((${moveMutativeQueryToCte$1(ctx, arg)}))`;
1906
- }
1907
- return addValue(ctx.values, JSON.stringify(arg)) + "::jsonb";
1908
- };
1909
- const serializeJsonValue = (arg, ctx, quotedAs) => {
1910
- if (arg && typeof arg === "object") {
1911
- if (isExpression(arg)) return "to_jsonb(" + arg.toSQL(ctx, quotedAs) + ")";
1912
- if ("toSQL" in arg) return `to_jsonb((${moveMutativeQueryToCte$1(ctx, arg)}))`;
1913
- }
1914
- return addValue(ctx.values, JSON.stringify(arg));
1915
- };
1916
- const Operators = {
1917
- any: base,
1918
- boolean,
1919
- ordinalText,
1920
- number: ord,
1921
- date: ord,
1922
- time: ord,
1923
- text,
1924
- json: {
1925
- ...ord,
1926
- equals: make((key, value, ctx, quotedAs) => value === null ? `nullif(${key}, 'null'::jsonb) IS NULL` : `${key} = ${quoteJsonValue(value, ctx, quotedAs)}`),
1927
- not: make((key, value, ctx, quotedAs) => value === null ? `nullif(${key}, 'null'::jsonb) IS NOT NULL` : `${key} != ${quoteJsonValue(value, ctx, quotedAs)}`),
1928
- in: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "false" : `${key} IN ${quoteJsonValue(value, ctx, quotedAs, true)}`),
1929
- notIn: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "true" : `NOT ${key} IN ${quoteJsonValue(value, ctx, quotedAs, true)}`),
1930
- jsonPathQueryFirst: Object.assign(function(path, options) {
1931
- const { q, columnTypes } = this;
1932
- const chain = q.chain ??= [];
1933
- chain.push(jsonPathQueryOp, [path, options]);
1934
- if (q.parsers?.[getValueKey]) setObjectValueImmutable(q, "parsers", getValueKey, void 0);
1935
- if (options?.type) {
1936
- const type = options.type(columnTypes);
1937
- addColumnParserToQuery(q, getValueKey, type);
1938
- chain.push = (...args) => {
1939
- chain.push = Array.prototype.push;
1940
- chain.push((s) => `${s}::${type.dataType}`, emptyArray);
1941
- return chain.push(...args);
1942
- };
1943
- return setQueryOperators(this, type.operators);
1944
- }
1945
- return this;
1946
- }, { _op: jsonPathQueryOp }),
1947
- jsonSupersetOf: make((key, value, ctx, quotedAs) => `${key} @> ${quoteValue(value, ctx, quotedAs)}`),
1948
- jsonSubsetOf: make((key, value, ctx, quotedAs) => `${key} <@ ${quoteValue(value, ctx, quotedAs)}`),
1949
- jsonSet: makeVarArg((key, [path, value], ctx, quotedAs) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)})`),
1950
- jsonReplace: makeVarArg((key, [path, value], ctx, quotedAs) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)}, false)`),
1951
- jsonInsert: makeVarArg((key, [path, value, options], ctx, quotedAs) => `jsonb_insert(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)}${options?.after ? ", true" : ""})`),
1952
- jsonRemove: makeVarArg((key, [path], ctx) => `(${key} #- ${encodeJsonPath(ctx, path)})`)
1953
- },
1954
- array: {
1955
- ...ord,
1956
- has: make((key, value, ctx, quotedAs) => `${quoteValue(value, ctx, quotedAs)} = ANY(${key})`),
1957
- hasEvery: make((key, value, ctx, quotedAs) => `${key} @> ${quoteValue(value, ctx, quotedAs)}`),
1958
- hasSome: make((key, value, ctx, quotedAs) => `${key} && ${quoteValue(value, ctx, quotedAs)}`),
1959
- containedIn: make((key, value, ctx, quotedAs) => `${key} <@ ${quoteValue(value, ctx, quotedAs)}`),
1960
- length: make((key, value, ctx, quotedAs) => {
1961
- const expr = `COALESCE(array_length(${key}, 1), 0)`;
1962
- return typeof value === "number" ? `${expr} = ${quoteValue(value, ctx, quotedAs)}` : Object.keys(value).map((key) => ord[key]._op(expr, value[key], ctx, quotedAs)).join(" AND ");
1963
- })
1964
- }
1965
- };
1966
1833
  const dateToString = (value) => value.toISOString();
1967
1834
  const dateTimeEncode = (value) => {
1968
1835
  return typeof value === "number" ? new Date(value) : value;
@@ -2090,7 +1957,6 @@ var ArrayColumn = class ArrayColumn extends Column {
2090
1957
  this.dataType = "array";
2091
1958
  this.operators = Operators.array;
2092
1959
  item.data.isNullable = true;
2093
- setColumnDefaultParse(this, (input) => parse$1.call(this, input));
2094
1960
  if (defaultEncode) setColumnDefaultEncode(this, defaultEncode);
2095
1961
  this.data.item = item instanceof ArrayColumn ? item.data.item : item;
2096
1962
  this.data.name = item.data.name;
@@ -2116,54 +1982,6 @@ var ArrayColumn = class ArrayColumn extends Column {
2116
1982
  return columnCode(this, ctx, key, code);
2117
1983
  }
2118
1984
  };
2119
- const parse$1 = function(source) {
2120
- if (typeof source !== "string") return source;
2121
- const entries = [];
2122
- parsePostgresArray(source, entries, this.data.item.data.parseItem);
2123
- return entries;
2124
- };
2125
- /**
2126
- * based on https://github.com/bendrucker/postgres-array/tree/master
2127
- * and slightly optimized
2128
- */
2129
- const parsePostgresArray = (source, entries, transform) => {
2130
- let pos = 0;
2131
- if (source[0] === "[") {
2132
- pos = source.indexOf("=") + 1;
2133
- if (!pos) pos = source.length;
2134
- }
2135
- if (source[pos] === "{") pos++;
2136
- let recorded = "";
2137
- while (pos < source.length) {
2138
- const character = source[pos++];
2139
- if (character === "{") {
2140
- const innerEntries = [];
2141
- entries.push(innerEntries);
2142
- pos += parsePostgresArray(source.slice(pos - 1), innerEntries, transform) - 1;
2143
- } else if (character === "}") {
2144
- if (recorded) entries.push(recorded === "NULL" ? null : transform ? transform(recorded) : recorded);
2145
- return pos;
2146
- } else if (character === "\"") {
2147
- let esc = false;
2148
- let rec = "";
2149
- while (pos < source.length) {
2150
- let char;
2151
- while ((char = source[pos++]) === "\\") if (!(esc = !esc)) rec += "\\";
2152
- if (esc) esc = false;
2153
- else if (char === "\"") break;
2154
- rec += char;
2155
- }
2156
- entries.push(transform ? transform(rec) : rec);
2157
- recorded = "";
2158
- } else if (character === ",") {
2159
- if (recorded) {
2160
- entries.push(recorded === "NULL" ? null : transform ? transform(recorded) : recorded);
2161
- recorded = "";
2162
- }
2163
- } else recorded += character;
2164
- }
2165
- return pos;
2166
- };
2167
1985
  const encodeJson = (x) => x === null ? x : JSON.stringify(x);
2168
1986
  var JSONColumn = class extends Column {
2169
1987
  constructor(schema, __inputType, encodedByDriver = true) {
@@ -2419,6 +2237,202 @@ const defaultSchemaConfig = (options) => {
2419
2237
  return schemaConfig;
2420
2238
  };
2421
2239
  const internalSchemaConfig = defaultSchemaConfig();
2240
+ var BooleanColumn = class BooleanColumn extends Column {
2241
+ static get instance() {
2242
+ return this._instance ??= new BooleanColumn(internalSchemaConfig);
2243
+ }
2244
+ static get instanceSkipValueToArray() {
2245
+ let instance = this._instanceSkipValueToArray;
2246
+ if (!instance) {
2247
+ instance = this._instanceSkipValueToArray = Object.create(this.instance);
2248
+ instance.data.skipValueToArray = true;
2249
+ }
2250
+ return instance;
2251
+ }
2252
+ constructor(schema) {
2253
+ super(schema, schema.boolean());
2254
+ this.dataType = "bool";
2255
+ this.operators = Operators.boolean;
2256
+ this.data.alias = "boolean";
2257
+ this.data.parseItem = parseItem;
2258
+ }
2259
+ toCode(ctx, key) {
2260
+ return columnCode(this, ctx, key, "boolean()");
2261
+ }
2262
+ };
2263
+ const parseItem = (input) => input[0] === "t";
2264
+ let moveMutativeQueryToCte$1;
2265
+ const setMoveMutativeQueryToCte = (fn) => {
2266
+ moveMutativeQueryToCte$1 = fn;
2267
+ };
2268
+ let prepareSubQueryForSql$1;
2269
+ const setPrepareSubQueryForSql = (fn) => {
2270
+ prepareSubQueryForSql$1 = fn;
2271
+ };
2272
+ let dbClass;
2273
+ const setDb = (db) => {
2274
+ dbClass = db;
2275
+ };
2276
+ function setQueryOperators(query, operators) {
2277
+ const q = query.q;
2278
+ if (q.operators !== operators) {
2279
+ q.operators = operators;
2280
+ Object.assign(query, operators);
2281
+ }
2282
+ return query;
2283
+ }
2284
+ /**
2285
+ * Makes operator function that has `_op` property.
2286
+ *
2287
+ * @param _op - function to turn the operator call into SQL.
2288
+ */
2289
+ const make = (_op) => {
2290
+ return Object.assign(function(value) {
2291
+ const { q } = this;
2292
+ const val = prepareOpArg(this, value);
2293
+ (q.chain ??= []).push(_op, val || value);
2294
+ if (getValueParser(q.parsers)) setValueParser(q, void 0);
2295
+ q.getColumn = BooleanColumn.instance;
2296
+ return setQueryOperators(this, boolean);
2297
+ }, { _op });
2298
+ };
2299
+ const makeVarArg = (_op) => {
2300
+ return Object.assign(function(...args) {
2301
+ const { q } = this;
2302
+ args.forEach((arg, i) => {
2303
+ const val = prepareOpArg(this, arg);
2304
+ if (val) args[i] = val;
2305
+ });
2306
+ (q.chain ??= []).push(_op, args);
2307
+ if (getValueParser(q.parsers)) setValueParser(q, void 0);
2308
+ return setQueryOperators(this, boolean);
2309
+ }, { _op });
2310
+ };
2311
+ const prepareOpArg = (q, arg) => {
2312
+ return arg instanceof dbClass ? prepareSubQueryForSql$1(q, arg) : void 0;
2313
+ };
2314
+ const quoteValue = (arg, ctx, quotedAs, IN) => {
2315
+ if (arg && typeof arg === "object") {
2316
+ if (IN && isIterable(arg)) return `(${(Array.isArray(arg) ? arg : [...arg]).map((value) => addValue(ctx.values, value)).join(", ")})`;
2317
+ if (isExpression(arg)) return arg.toSQL(ctx, quotedAs);
2318
+ if ("toSQL" in arg) return `(${moveMutativeQueryToCte$1(ctx, arg)})`;
2319
+ if (!(arg instanceof Date) && !Array.isArray(arg)) arg = JSON.stringify(arg);
2320
+ }
2321
+ return addValue(ctx.values, arg);
2322
+ };
2323
+ const quoteLikeValue = (arg, ctx, quotedAs, jsonArray) => {
2324
+ if (arg && typeof arg === "object") {
2325
+ if (!jsonArray && Array.isArray(arg)) return `(${arg.map((value) => addValue(ctx.values, value)).join(", ")})`;
2326
+ if (isExpression(arg)) return arg.toSQL(ctx, quotedAs);
2327
+ if ("toSQL" in arg) return `replace(replace((${moveMutativeQueryToCte$1(ctx, arg)}), '%', '\\\\%'), '_', '\\\\_')`;
2328
+ }
2329
+ return addValue(ctx.values, arg.replace(/[%_]/g, "\\$&"));
2330
+ };
2331
+ const base = {
2332
+ equals: make((key, value, ctx, quotedAs) => value === null ? `${key} IS NULL` : `${key} = ${quoteValue(value, ctx, quotedAs)}`),
2333
+ not: make((key, value, ctx, quotedAs) => value === null ? `${key} IS NOT NULL` : `${key} <> ${quoteValue(value, ctx, quotedAs)}`),
2334
+ isDistinctFrom: make((key, value, ctx, quotedAs) => `${key} IS DISTINCT FROM ${quoteValue(value, ctx, quotedAs)}`),
2335
+ isNotDistinctFrom: make((key, value, ctx, quotedAs) => `${key} IS NOT DISTINCT FROM ${quoteValue(value, ctx, quotedAs)}`),
2336
+ in: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "false" : `${key} IN ${quoteValue(value, ctx, quotedAs, true)}`),
2337
+ notIn: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "true" : `NOT ${key} IN ${quoteValue(value, ctx, quotedAs, true)}`)
2338
+ };
2339
+ const ord = {
2340
+ ...base,
2341
+ lt: make((key, value, ctx, quotedAs) => `${key} < ${quoteValue(value, ctx, quotedAs)}`),
2342
+ lte: make((key, value, ctx, quotedAs) => `${key} <= ${quoteValue(value, ctx, quotedAs)}`),
2343
+ gt: make((key, value, ctx, quotedAs) => `${key} > ${quoteValue(value, ctx, quotedAs)}`),
2344
+ gte: make((key, value, ctx, quotedAs) => `${key} >= ${quoteValue(value, ctx, quotedAs)}`),
2345
+ between: make((key, [from, to], ctx, quotedAs) => `${key} BETWEEN ${quoteValue(from, ctx, quotedAs)} AND ${quoteValue(to, ctx, quotedAs)}`)
2346
+ };
2347
+ const boolean = {
2348
+ ...ord,
2349
+ and: make((key, value, ctx, quotedAs) => `${key} AND ${value.q.expr.toSQL(ctx, quotedAs)}`),
2350
+ or: make((key, value, ctx, quotedAs) => `(${key}) OR (${value.q.expr.toSQL(ctx, quotedAs)})`)
2351
+ };
2352
+ const text = {
2353
+ ...base,
2354
+ contains: make((key, value, ctx, quotedAs) => `${key} ILIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
2355
+ containsSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
2356
+ startsWith: make((key, value, ctx, quotedAs) => `${key} ILIKE ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
2357
+ startsWithSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE ${quoteLikeValue(value, ctx, quotedAs)} || '%'`),
2358
+ endsWith: make((key, value, ctx, quotedAs) => `${key} ILIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)}`),
2359
+ endsWithSensitive: make((key, value, ctx, quotedAs) => `${key} LIKE '%' || ${quoteLikeValue(value, ctx, quotedAs)}`)
2360
+ };
2361
+ const ordinalText = {
2362
+ ...ord,
2363
+ ...text
2364
+ };
2365
+ const encodeJsonPath = (ctx, path) => addValue(ctx.values, `{${Array.isArray(path) ? path.join(", ") : path}}`);
2366
+ 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" : ""})`;
2367
+ const shouldEncodeJson = (ctx) => ctx.q.adapter.driverAdapter.schemaConfig?.jsonEncodedByDriver === false;
2368
+ const quoteJsonValue = (arg, ctx, quotedAs, IN) => {
2369
+ if (arg && typeof arg === "object") {
2370
+ if (IN && Array.isArray(arg)) return `(${arg.map((value) => shouldEncodeJson(ctx) ? addValue(ctx.values, JSON.stringify(value)) : addValue(ctx.values, value)).join(", ")})`;
2371
+ if (Array.isArray(arg)) return shouldEncodeJson(ctx) ? addValue(ctx.values, JSON.stringify(arg)) : addValue(ctx.values, arg);
2372
+ if (isExpression(arg)) return "to_jsonb(" + arg.toSQL(ctx, quotedAs) + ")";
2373
+ if ("toSQL" in arg) return `to_jsonb((${moveMutativeQueryToCte$1(ctx, arg)}))`;
2374
+ }
2375
+ return shouldEncodeJson(ctx) ? addValue(ctx.values, JSON.stringify(arg)) : addValue(ctx.values, arg);
2376
+ };
2377
+ const serializeJsonValue = (arg, ctx, quotedAs) => {
2378
+ if (arg && typeof arg === "object") {
2379
+ if (isExpression(arg)) return "to_jsonb(" + arg.toSQL(ctx, quotedAs) + ")";
2380
+ if ("toSQL" in arg) return `to_jsonb((${moveMutativeQueryToCte$1(ctx, arg)}))`;
2381
+ }
2382
+ return addValue(ctx.values, JSON.stringify(arg));
2383
+ };
2384
+ const Operators = {
2385
+ any: base,
2386
+ boolean,
2387
+ ordinalText,
2388
+ number: ord,
2389
+ date: ord,
2390
+ time: ord,
2391
+ text,
2392
+ json: {
2393
+ ...ord,
2394
+ equals: make((key, value, ctx, quotedAs) => value === null ? `nullif(${key}, 'null'::jsonb) IS NULL` : `${key} = ${quoteJsonValue(value, ctx, quotedAs)}`),
2395
+ not: make((key, value, ctx, quotedAs) => value === null ? `nullif(${key}, 'null'::jsonb) IS NOT NULL` : `${key} != ${quoteJsonValue(value, ctx, quotedAs)}`),
2396
+ isDistinctFrom: make((key, value, ctx, quotedAs) => `${key} IS DISTINCT FROM ${quoteJsonValue(value, ctx, quotedAs)}`),
2397
+ isNotDistinctFrom: make((key, value, ctx, quotedAs) => `${key} IS NOT DISTINCT FROM ${quoteJsonValue(value, ctx, quotedAs)}`),
2398
+ in: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "false" : `${key} IN ${quoteJsonValue(value, ctx, quotedAs, true)}`),
2399
+ notIn: make((key, value, ctx, quotedAs) => Array.isArray(value) && !value.length ? "true" : `NOT ${key} IN ${quoteJsonValue(value, ctx, quotedAs, true)}`),
2400
+ jsonPathQueryFirst: Object.assign(function(path, options) {
2401
+ const { q, columnTypes } = this;
2402
+ const chain = q.chain ??= [];
2403
+ chain.push(jsonPathQueryOp, [path, options]);
2404
+ if (getValueParser(q.parsers)) setValueParser(q, void 0);
2405
+ if (options?.type) {
2406
+ const type = options.type(columnTypes);
2407
+ setValueParserToQuery(q, type);
2408
+ chain.push = (...args) => {
2409
+ chain.push = Array.prototype.push;
2410
+ chain.push((s) => `${s}::${type.dataType}`, emptyArray);
2411
+ return chain.push(...args);
2412
+ };
2413
+ return setQueryOperators(this, type.operators);
2414
+ }
2415
+ return this;
2416
+ }, { _op: jsonPathQueryOp }),
2417
+ jsonSupersetOf: make((key, value, ctx, quotedAs) => `${key} @> ${quoteValue(value, ctx, quotedAs)}`),
2418
+ jsonSubsetOf: make((key, value, ctx, quotedAs) => `${key} <@ ${quoteValue(value, ctx, quotedAs)}`),
2419
+ jsonSet: makeVarArg((key, [path, value], ctx, quotedAs) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)})`),
2420
+ jsonReplace: makeVarArg((key, [path, value], ctx, quotedAs) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)}, false)`),
2421
+ jsonInsert: makeVarArg((key, [path, value, options], ctx, quotedAs) => `jsonb_insert(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(value, ctx, quotedAs)}${options?.after ? ", true" : ""})`),
2422
+ jsonRemove: makeVarArg((key, [path], ctx) => `(${key} #- ${encodeJsonPath(ctx, path)})`)
2423
+ },
2424
+ array: {
2425
+ ...ord,
2426
+ has: make((key, value, ctx, quotedAs) => `${quoteValue(value, ctx, quotedAs)} = ANY(${key})`),
2427
+ hasEvery: make((key, value, ctx, quotedAs) => `${key} @> ${quoteValue(value, ctx, quotedAs)}`),
2428
+ hasSome: make((key, value, ctx, quotedAs) => `${key} && ${quoteValue(value, ctx, quotedAs)}`),
2429
+ containedIn: make((key, value, ctx, quotedAs) => `${key} <@ ${quoteValue(value, ctx, quotedAs)}`),
2430
+ length: make((key, value, ctx, quotedAs) => {
2431
+ const expr = `COALESCE(array_length(${key}, 1), 0)`;
2432
+ return typeof value === "number" ? `${expr} = ${quoteValue(value, ctx, quotedAs)}` : Object.keys(value).map((key) => ord[key]._op(expr, value[key], ctx, quotedAs)).join(" AND ");
2433
+ })
2434
+ }
2435
+ };
2422
2436
  var TextBaseColumn = class extends Column {
2423
2437
  constructor(schema, schemaType = schema.stringSchema()) {
2424
2438
  super(schema, schemaType);
@@ -2778,22 +2792,6 @@ var CitextColumn = class extends TextBaseColumn {
2778
2792
  return textColumnToCode(this, ctx, key);
2779
2793
  }
2780
2794
  };
2781
- var BooleanColumn = class BooleanColumn extends Column {
2782
- static get instance() {
2783
- return this._instance ??= new BooleanColumn(internalSchemaConfig);
2784
- }
2785
- constructor(schema) {
2786
- super(schema, schema.boolean());
2787
- this.dataType = "bool";
2788
- this.operators = Operators.boolean;
2789
- this.data.alias = "boolean";
2790
- this.data.parseItem = parseItem;
2791
- }
2792
- toCode(ctx, key) {
2793
- return columnCode(this, ctx, key, "boolean()");
2794
- }
2795
- };
2796
- const parseItem = (input) => input[0] === "t";
2797
2795
  var SimpleRawSQL = class extends RawSql {
2798
2796
  makeSQL() {
2799
2797
  return this._sql;
@@ -3430,29 +3428,6 @@ var QueryHooks = class {
3430
3428
  }
3431
3429
  };
3432
3430
  /**
3433
- * generic utility to add a parser to the query object
3434
- * @param query - the query object, it will be mutated
3435
- * @param key - the name of the column in the data loaded by the query
3436
- * @param parser - function to process the value of the column with.
3437
- */
3438
- const setParserToQuery = (query, key, parser) => {
3439
- if (parser) if (query.parsers) query.parsers[key] = parser;
3440
- else query.parsers = { [key]: parser };
3441
- else if (query.parsers) delete query.parsers[key];
3442
- };
3443
- const getQueryParsers = (q, hookSelect) => {
3444
- if (hookSelect) {
3445
- const parsers = { ...q.q.parsers };
3446
- const { defaultParsers } = q.q;
3447
- if (defaultParsers) for (const [key, value] of hookSelect) {
3448
- const parser = defaultParsers[key];
3449
- if (parser) parsers[value.as || key] = parser;
3450
- }
3451
- return parsers;
3452
- }
3453
- return q.q.select ? q.q.parsers : q.q.defaultParsers;
3454
- };
3455
- /**
3456
3431
  * In snake case mode, or when columns have custom names,
3457
3432
  * use this method to exchange a db column name to its runtime key.
3458
3433
  */
@@ -4503,7 +4478,7 @@ const requirePrimaryKeys = (q, message) => {
4503
4478
  };
4504
4479
  const collectPrimaryKeys = (q) => {
4505
4480
  const primaryKeys = [];
4506
- const { shape } = q.q;
4481
+ const { shape } = q;
4507
4482
  for (const key in shape) if (shape[key].data.primaryKey) primaryKeys.push(key);
4508
4483
  const pkey = q.internal.tableData.primaryKey;
4509
4484
  if (pkey) primaryKeys.push(...pkey.columns);
@@ -4745,7 +4720,7 @@ const then = async (q, adapter, state, beforeHooks, afterHooks, afterSaveHooks,
4745
4720
  }
4746
4721
  const { tableHook, cteHooks } = sql;
4747
4722
  const { returnType = "all" } = query;
4748
- const tempReturnType = tableHook?.select || cteHooks?.hasSelect || returnType === "rows" && (q.q.batchParsers || adapter.driverAdapter.noFieldsForArrays) || checkIfNeedResultAllForMutativeQueriesSelectRelations(sql) ? "all" : returnType;
4723
+ const tempReturnType = tableHook?.select || cteHooks?.hasSelect || q.q.batchParsers || adapter.driverAdapter.noFieldsForArrays || checkIfNeedResultAllForMutativeQueriesSelectRelations(sql) ? "all" : returnType;
4749
4724
  let result;
4750
4725
  let queryResult;
4751
4726
  let cteData;
@@ -5001,12 +4976,25 @@ const execQuery = (adapter, method, sql, startingSavepoint, releasingSavepoint,
5001
4976
  });
5002
4977
  };
5003
4978
  const handleResult = (q, returnType, result, sql, isSubQuery) => {
5004
- const parsers = getQueryParsers(q, sql.tableHook?.select);
4979
+ let parsers = getQueryParsers(q, sql.tableHook?.select);
5005
4980
  switch (returnType) {
5006
4981
  case "all": {
5007
4982
  if (q.q.throwOnNotFound && result.rows.length === 0) throw new NotFoundError(q);
5008
4983
  const { rows } = result;
5009
- if (parsers) for (const row of rows) parseRecord(parsers, row);
4984
+ if (q.q.returnType === "value" || q.q.returnType === "valueOrThrow") {
4985
+ if (!rows.length) if (!q.q.select) return rows;
4986
+ else {
4987
+ if (q.q.returnType === "valueOrThrow") throw new NotFoundError(q);
4988
+ return [{ value: q.q.notFoundDefault }];
4989
+ }
4990
+ if (parsers) {
4991
+ const parser = getValueParser(parsers);
4992
+ if (parser) {
4993
+ const hookSelect = sql.tableHook?.select;
4994
+ for (const row of rows) for (const key in row) if (!hookSelect?.has(key)) row[key] = parser(row[key]);
4995
+ }
4996
+ }
4997
+ } else if (parsers) for (const row of rows) parseRecord(parsers, row);
5010
4998
  return rows;
5011
4999
  }
5012
5000
  case "one": {
@@ -5028,7 +5016,7 @@ const handleResult = (q, returnType, result, sql, isSubQuery) => {
5028
5016
  }
5029
5017
  case "pluck": {
5030
5018
  const { rows } = result;
5031
- parsePluck(parsers, isSubQuery, rows);
5019
+ parsePluck(q, parsers, isSubQuery, rows);
5032
5020
  return rows;
5033
5021
  }
5034
5022
  case "value": {
@@ -5065,14 +5053,26 @@ const parseRows = (parsers, fields, rows) => {
5065
5053
  if (parser) for (const row of rows) row[i] = parser(row[i]);
5066
5054
  }
5067
5055
  };
5068
- const parsePluck = (parsers, isSubQuery, rows) => {
5069
- const pluck = parsers?.pluck;
5070
- if (pluck) for (let i = 0; i < rows.length; i++) rows[i] = pluck(isSubQuery ? rows[i] : rows[i][0]);
5056
+ const parsePluck = (query, parsers, isSubQuery, rows) => {
5057
+ const valueToArray = query.q.getColumn?.data?.valueToArray;
5058
+ const parse = parsers?.pluck;
5059
+ if (parse) if (valueToArray) for (let i = 0; i < rows.length; i++) {
5060
+ const value = isSubQuery ? rows[i] : rows[i][0];
5061
+ rows[i] = value === null ? void 0 : value[0] === null ? null : parse(value[0]);
5062
+ }
5063
+ else for (let i = 0; i < rows.length; i++) {
5064
+ const value = isSubQuery ? rows[i] : rows[i][0];
5065
+ rows[i] = value === null ? value : parse(value);
5066
+ }
5067
+ else if (valueToArray) for (let i = 0; i < rows.length; i++) {
5068
+ const value = isSubQuery ? rows[i] : rows[i][0];
5069
+ rows[i] = value === null ? void 0 : value[0];
5070
+ }
5071
5071
  else if (!isSubQuery) for (let i = 0; i < rows.length; i++) rows[i] = rows[i][0];
5072
5072
  };
5073
5073
  const parseValue = (value, parsers) => {
5074
- const parser = parsers?.[getValueKey];
5075
- return parser ? parser(value) : value;
5074
+ const parse = getValueParser(parsers);
5075
+ return parse ? parse(value) : value;
5076
5076
  };
5077
5077
  const filterResult = (q, returnType, queryResult, result, tempColumns, hasAfterHook) => {
5078
5078
  if (returnType === "all") return filterAllResult(result, tempColumns, hasAfterHook);
@@ -5105,7 +5105,7 @@ const filterResult = (q, returnType, queryResult, result, tempColumns, hasAfterH
5105
5105
  }
5106
5106
  };
5107
5107
  const getFirstResultKey = (q, queryResult) => {
5108
- if (q.q.select) return queryResult.fields[0].name;
5108
+ if (q.q.select) return queryResult.fields[0] ? queryResult.fields[0].name : "value";
5109
5109
  else for (const key in q.q.selectedComputeds) return key;
5110
5110
  };
5111
5111
  const filterAllResult = (result, tempColumns, hasAfterHook) => {
@@ -5364,7 +5364,7 @@ function queryFrom(self, arg) {
5364
5364
  if (typeof arg === "string") {
5365
5365
  data.as ||= arg;
5366
5366
  const w = data.withShapes?.[arg];
5367
- data.shape = w?.shape ?? anyShape;
5367
+ data.selectShape = w?.shape ?? anyShape;
5368
5368
  data.runtimeComputeds = w?.computeds;
5369
5369
  const parsers = {};
5370
5370
  data.defaultParsers = parsers;
@@ -5375,7 +5375,7 @@ function queryFrom(self, arg) {
5375
5375
  arg = arg.slice(i + 1);
5376
5376
  } else if (w) data.schema = void 0;
5377
5377
  } else if (Array.isArray(arg)) {
5378
- const shape = { ...data.shape };
5378
+ const shape = { ...data.selectShape };
5379
5379
  const joinedParsers = {};
5380
5380
  for (const item of arg) if (typeof item === "string") {
5381
5381
  const w = data.withShapes[item];
@@ -5397,7 +5397,7 @@ function queryFrom(self, arg) {
5397
5397
  } else {
5398
5398
  const q = prepareSubQueryForSql(self, arg);
5399
5399
  data.as ||= q.q.as || q.table || "t";
5400
- data.shape = getShapeFromSelect(q, true);
5400
+ data.selectShape = getShapeFromSelect(q, true);
5401
5401
  data.defaultParsers = getQueryParsers(q);
5402
5402
  data.batchParsers = q.q.batchParsers;
5403
5403
  }
@@ -5594,7 +5594,7 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, shape, whereExists,
5594
5594
  const j = joinTo.qb.baseQuery.clone();
5595
5595
  j.table = first;
5596
5596
  j.q = {
5597
- shape: w.shape,
5597
+ selectShape: w.shape,
5598
5598
  runtimeComputeds: w.computeds,
5599
5599
  adapter: joinToQ.adapter,
5600
5600
  handleResult: joinToQ.handleResult,
@@ -5676,7 +5676,7 @@ const makeJoinQueryBuilder = (joinedQuery, joinedShapes, joinTo, shape) => {
5676
5676
  q.q.joinedShapes = joinedShapes;
5677
5677
  q.q.joinTo = joinTo;
5678
5678
  if (q.q.scopes) q.q.scopes = void 0;
5679
- if (shape) q.q.shape = shape;
5679
+ if (shape) q.q.selectShape = shape;
5680
5680
  return q;
5681
5681
  };
5682
5682
  const isRelationQuery = (q) => "joinQuery" in q;
@@ -6503,7 +6503,7 @@ const _chain = (fromQuery, toQuery, rel) => {
6503
6503
  }];
6504
6504
  _applyRelationAliases(self, q);
6505
6505
  q.joinedShapes = {
6506
- [getQueryAs(self)]: self.q.shape,
6506
+ [getQueryAs(self)]: self.q.selectShape,
6507
6507
  ...self.q.joinedShapes
6508
6508
  };
6509
6509
  rel.modifyRelatedQuery?.(query)?.(self);
@@ -6540,131 +6540,78 @@ const resolveSubQueryCallback = (q, cb) => {
6540
6540
  _setSubQueryAliases(arg);
6541
6541
  return cb(arg);
6542
6542
  };
6543
- /**
6544
- * Acts as {@link simpleExistingColumnToSQL} except that the column is optional and will return quoted key if no column.
6545
- */
6546
- function simpleColumnToSQL(ctx, key, column, quotedAs) {
6547
- if (!column) return `"${key}"`;
6548
- const { data } = column;
6549
- return data.computed ? `(${data.computed.toSQL(ctx, quotedAs)})` : `${quotedAs ? `${quotedAs}.` : ""}"${data.name || key}"`;
6550
- }
6551
- function simpleExistingColumnToSQL(ctx, key, column, quotedAs) {
6552
- const { data } = column;
6553
- return data.computed ? `(${data.computed.toSQL(ctx, quotedAs)})` : `${quotedAs ? `${quotedAs}.` : ""}"${data.name || key}"`;
6554
- }
6555
- const columnToSql = (ctx, data, shape, column, quotedAs, select) => {
6556
- let index = column.indexOf(".");
6557
- if (index === -1) {
6558
- const joinAs = data.valuesJoinedAs?.[column];
6559
- if (joinAs) {
6560
- column = joinAs + "." + column;
6561
- index = joinAs.length;
6543
+ function simpleColumnToSQL(ctx, queryData, shape, key, column, quotedAs, select, as, jsonList, useSelectList, skipSelectSql, skipValueToArray) {
6544
+ let sql;
6545
+ let dontAlias;
6546
+ if (useSelectList && queryData.select) {
6547
+ for (const s of queryData.select) if (typeof s === "object" && "selectAs" in s) {
6548
+ if (key in s.selectAs) {
6549
+ dontAlias = true;
6550
+ sql = simpleColumnToSQL(ctx, queryData, shape, key, shape[key], void 0, void 0, void 0, void 0, void 0, void 0, true);
6551
+ break;
6552
+ }
6562
6553
  }
6563
6554
  }
6564
- if (index !== -1) return columnWithDotToSql(ctx, data, shape, column, index, quotedAs, select);
6565
- return simpleColumnToSQL(ctx, column, shape[column], quotedAs);
6566
- };
6567
- const selectedColumnToSql = (ctx, data, shape, column, quotedAs) => {
6568
- const index = column.indexOf(".");
6569
- return index !== -1 ? selectedColumnWithDotToSql(ctx, data, shape, column, index, quotedAs) : selectedSimpleColumnToSql(ctx, column, shape[column], quotedAs);
6570
- };
6571
- const selectedSimpleColumnToSql = (ctx, key, column, quotedAs) => {
6572
- if (!column) return `"${key}"`;
6573
- const { data } = column;
6574
- return data.selectSql ? `(${data.selectSql.toSQL(ctx, quotedAs)})` : `${quotedAs ? `${quotedAs}.` : ""}"${data.name || key}"`;
6575
- };
6576
- /**
6577
- * in a case when ordering or grouping by a column which was selected as expression:
6578
- * ```ts
6579
- * table.select({ x: (q) => q.sum('x') }).group('x').order('x')
6580
- * ```
6581
- * the column must not be prefixed with a table name.
6582
- */
6583
- const maybeSelectedColumnToSql = (ctx, data, column, quotedAs) => {
6584
- const index = column.indexOf(".");
6585
- if (index !== -1) return columnWithDotToSql(ctx, data, data.shape, column, index, quotedAs);
6586
- else {
6587
- if (data.joinedShapes?.[column]) return `"${column}"."${column}"`;
6588
- if (data.select) {
6589
- for (const s of data.select) if (typeof s === "object" && "selectAs" in s) {
6590
- if (column in s.selectAs) return simpleColumnToSQL(ctx, column, data.shape[column]);
6555
+ if (!sql) if (!column) {
6556
+ dontAlias = key === as;
6557
+ sql = `${quotedAs ? `${quotedAs}.` : ""}"${key}"`;
6558
+ } else {
6559
+ if (jsonList && as) jsonList[as] = column && getSelectedColumnData(column);
6560
+ const { data } = column;
6561
+ if (select && data.selectSql && !skipSelectSql) sql = `(${data.selectSql.toSQL(ctx, quotedAs)})`;
6562
+ else if (data.computed) sql = `(${data.computed.toSQL(ctx, quotedAs)})`;
6563
+ else {
6564
+ const name = data.name || key;
6565
+ dontAlias = name === as;
6566
+ if (!select) {
6567
+ const joinAs = !select && queryData.valuesJoinedAs?.[key];
6568
+ if (joinAs) quotedAs = `"${joinAs}"`;
6591
6569
  }
6570
+ sql = `${quotedAs ? `${quotedAs}.` : ""}"${name}"`;
6592
6571
  }
6593
- return simpleColumnToSQL(ctx, column, data.shape[column], quotedAs);
6594
- }
6595
- };
6596
- const columnWithDotToSql = (ctx, data, shape, column, index, quotedAs, select) => {
6597
- const table = column.slice(0, index);
6598
- const key = column.slice(index + 1);
6599
- if (key === "*") {
6600
- const shape = data.joinedShapes?.[table];
6601
- return shape ? select ? makeRowToJson(ctx, table, shape, true) : `"${table}".*` : column;
6602
- }
6603
- const tableName = _getQueryAliasOrName(data, table);
6604
- const quoted = `"${table}"`;
6605
- const col = quoted === quotedAs ? shape[key] : data.joinedShapes?.[tableName]?.[key];
6606
- if (col) {
6607
- if (col.data.name) return `"${tableName}"."${col.data.name}"`;
6608
- if (col.data.computed) return `(${col.data.computed.toSQL(ctx, quoted)})`;
6609
- return `"${tableName}"."${key}"`;
6610
- }
6611
- return `"${tableName}"."${key}"`;
6612
- };
6613
- const selectedColumnWithDotToSql = (ctx, data, shape, column, index, quotedAs) => {
6614
- const table = column.slice(0, index);
6615
- const key = column.slice(index + 1);
6616
- if (key === "*") {
6617
- const shape = data.joinedShapes?.[table];
6618
- return shape ? makeRowToJson(ctx, table, shape, true) : column;
6619
- }
6620
- const tableName = _getQueryAliasOrName(data, table);
6621
- const quoted = `"${table}"`;
6622
- const col = quoted === quotedAs ? shape[key] : data.joinedShapes?.[tableName]?.[key];
6623
- if (col) {
6624
- if (col.data.selectSql) return `(${col.data.selectSql.toSQL(ctx, quoted)})`;
6625
- if (col.data.name) return `"${tableName}"."${col.data.name}"`;
6626
6572
  }
6627
- return `"${tableName}"."${key}"`;
6628
- };
6629
- const columnToSqlWithAs = (ctx, data, column, as, quotedAs, select, jsonList) => {
6630
- const index = column.indexOf(".");
6631
- 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);
6632
- };
6633
- const tableColumnToSqlWithAs = (ctx, data, column, table, key, as, quotedAs, select, jsonList) => {
6573
+ if (!select && !useSelectList && column?.data.valueToArray && !column.data.skipValueToArray) sql += "[1]";
6574
+ else if (queryData.getColumn?.data.valueToArray && !skipValueToArray) sql = `array[${sql}]`;
6575
+ if (as && !dontAlias) sql = `${sql} "${as}"`;
6576
+ return sql;
6577
+ }
6578
+ const tableColumnToSql = (ctx, queryData, shape, table, key, quotedAs, select, as, jsonList, skipValueToArray) => {
6579
+ let sql;
6580
+ let dontAlias;
6634
6581
  if (key === "*") {
6635
- if (jsonList) jsonList[as] = void 0;
6636
- const shape = data.joinedShapes?.[table];
6637
- if (shape) {
6638
- if (select) return makeRowToJson(ctx, table, shape, true) + ` "${as}"`;
6639
- return `"${table}"."${table}" "${as}"`;
6582
+ if (jsonList && as) jsonList[as] = void 0;
6583
+ const shape = queryData.joinedShapes?.[table];
6584
+ if (shape) sql = select ? makeRowToJson(ctx, table, shape, true) : `"${table}".*`;
6585
+ else {
6586
+ sql = `"${table}"."${key}"`;
6587
+ dontAlias = true;
6640
6588
  }
6641
- return column;
6642
- }
6643
- const tableName = _getQueryAliasOrName(data, table);
6644
- const quoted = `"${table}"`;
6645
- const col = quoted === quotedAs ? data.shape[key] : data.joinedShapes?.[tableName][key];
6646
- if (jsonList) jsonList[as] = col && getSelectedColumnData(col);
6647
- if (col) {
6648
- if (col.data.selectSql) return `(${col.data.selectSql.toSQL(ctx, quoted)}) "${as}"`;
6649
- if (col.data.name && col.data.name !== key) return `"${tableName}"."${col.data.name}" "${as}"`;
6589
+ } else {
6590
+ const tableName = _getQueryAliasOrName(queryData, table);
6591
+ const quoted = `"${table}"`;
6592
+ const col = quoted === quotedAs ? shape[key] : queryData.joinedShapes?.[tableName]?.[key];
6593
+ if (jsonList && as) jsonList[as] = col && getSelectedColumnData(col);
6594
+ if (col?.data.selectSql) sql = `(${col.data.selectSql.toSQL(ctx, quoted)})`;
6595
+ else if (col?.data.name) sql = `"${tableName}"."${col.data.name}"`;
6596
+ else if (col?.data.computed) sql = `(${col.data.computed.toSQL(ctx, quoted)})`;
6597
+ else {
6598
+ sql = `"${tableName}"."${key}"`;
6599
+ dontAlias = key === as;
6600
+ }
6601
+ if (!select && col?.data.valueToArray && !col.data.skipValueToArray) sql += "[1]";
6602
+ else if (queryData.getColumn?.data.valueToArray && !skipValueToArray) sql = `array[${sql}]`;
6650
6603
  }
6651
- return `"${tableName}"."${key}"${key === as ? "" : ` "${as}"`}`;
6604
+ if (as && !dontAlias) sql = `${sql} "${as}"`;
6605
+ return sql;
6652
6606
  };
6653
- const ownColumnToSqlWithAs = (ctx, data, column, as, quotedAs, select, jsonList) => {
6654
- if (!select && data.joinedShapes?.[column]) {
6655
- if (jsonList) jsonList[as] = void 0;
6656
- return `"${column}"."${column}" "${as}"`;
6657
- }
6658
- const col = data.shape[column];
6659
- if (jsonList) jsonList[as] = col && getSelectedColumnData(col);
6660
- if (col) {
6661
- if (col.data.selectSql) return `(${col.data.selectSql.toSQL(ctx, quotedAs)}) "${as}"`;
6662
- if (col.data.name && col.data.name !== column) return `${quotedAs ? `${quotedAs}.` : ""}"${col.data.name}"${col.data.name === as ? "" : ` "${as}"`}`;
6663
- }
6664
- return `${quotedAs ? `${quotedAs}.` : ""}"${column}"${column === as ? "" : ` "${as}"`}`;
6607
+ const columnToSqlNotSelect = (ctx, data, shape, column, quotedAs, useSelectList) => columnToSql(ctx, data, shape, column, quotedAs, void 0, void 0, void 0, useSelectList, true);
6608
+ const columnToSql = (ctx, data, shape, column, quotedAs, select, as, jsonList, useSelectList, skipValueToArray) => {
6609
+ let index = column.indexOf(".");
6610
+ if (index !== -1) return tableColumnToSql(ctx, data, shape, column.slice(0, index), column.slice(index + 1), quotedAs, select, as, jsonList, skipValueToArray);
6611
+ return simpleColumnToSQL(ctx, data, shape, column, shape[column], quotedAs, select, as, jsonList, useSelectList, void 0, skipValueToArray);
6665
6612
  };
6666
- const rawOrColumnToSql = (ctx, data, expr, quotedAs, shape = data.shape, select) => {
6667
- return typeof expr === "string" ? columnToSql(ctx, data, shape, expr, quotedAs, select) : expr.toSQL(ctx, quotedAs);
6613
+ const rawOrColumnToSql = (ctx, data, shape, expr, quotedAs, select, skipValueToArray) => {
6614
+ return typeof expr === "string" ? columnToSql(ctx, data, shape, expr, quotedAs, select, void 0, void 0, void 0, skipValueToArray) : expr.toSQL(ctx, quotedAs);
6668
6615
  };
6669
6616
  const processJoinItem = (ctx, table, query, args, quotedAs) => {
6670
6617
  let target;
@@ -6724,7 +6671,7 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
6724
6671
  joinedShapes: {
6725
6672
  ...query.joinedShapes,
6726
6673
  ...q.q.joinedShapes,
6727
- [table.q.as || table.table]: table.q.shape
6674
+ [table.q.as || table.table]: table.q.selectShape
6728
6675
  }
6729
6676
  }, joinAs);
6730
6677
  if (whereSql) if (on) on += ` AND ${whereSql}`;
@@ -6773,17 +6720,17 @@ const getConditionsFor3Or4LengthItem = (ctx, query, target, quotedAs, args, join
6773
6720
  const [leftColumn, opOrRightColumn, maybeRightColumn] = args;
6774
6721
  const op = maybeRightColumn ? opOrRightColumn : "=";
6775
6722
  const rightColumn = maybeRightColumn ? maybeRightColumn : opOrRightColumn;
6776
- return `${rawOrColumnToSql(ctx, query, leftColumn, target, joinShape)} ${op} ${rawOrColumnToSql(ctx, query, rightColumn, quotedAs, query.shape)}`;
6723
+ return `${rawOrColumnToSql(ctx, query, joinShape, leftColumn, target)} ${op} ${rawOrColumnToSql(ctx, query, query.selectShape, rightColumn, quotedAs)}`;
6777
6724
  };
6778
6725
  const getObjectOrRawConditions = (ctx, query, data, quotedAs, joinAs, joinShape) => {
6779
6726
  if (data === true) return "true";
6780
6727
  else if (isExpression(data)) return data.toSQL(ctx, quotedAs);
6781
6728
  else {
6782
6729
  const pairs = [];
6783
- const shape = query.shape;
6730
+ const shape = query.selectShape;
6784
6731
  for (const key in data) {
6785
6732
  const value = data[key];
6786
- pairs.push(`${columnToSql(ctx, query, joinShape, key, joinAs)} = ${rawOrColumnToSql(ctx, query, value, quotedAs, shape)}`);
6733
+ pairs.push(`${columnToSqlNotSelect(ctx, query, joinShape, key, joinAs)} = ${rawOrColumnToSql(ctx, query, shape, value, quotedAs)}`);
6787
6734
  }
6788
6735
  return pairs.join(", ");
6789
6736
  }
@@ -6815,11 +6762,11 @@ var SelectItemExpression = class extends Expression {
6815
6762
  }
6816
6763
  makeSQL(ctx, quotedAs) {
6817
6764
  const q = this.q;
6818
- 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);
6765
+ 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);
6819
6766
  }
6820
6767
  };
6821
6768
  const _getSelectableColumn = (q, arg) => {
6822
- let type = q.q.shape[arg];
6769
+ let type = q.q.selectShape[arg];
6823
6770
  if (!type) {
6824
6771
  const index = arg.indexOf(".");
6825
6772
  if (index !== -1) {
@@ -6836,30 +6783,17 @@ const _get = (query, returnType, arg) => {
6836
6783
  const q = query.q;
6837
6784
  if (q.returning) q.returning = void 0;
6838
6785
  q.returnType = returnType;
6839
- let type;
6840
6786
  let value = arg;
6841
- if (typeof value === "function") {
6842
- const item = processSelectAsArg(query, getQueryAs(query), "value", value);
6843
- if (item !== false) value = item;
6844
- }
6845
- if (typeof value === "string") {
6846
- const joinedAs = q.valuesJoinedAs?.[value];
6847
- type = joinedAs ? q.joinedShapes?.[joinedAs]?.value : _getSelectableColumn(query, value);
6848
- q.getColumn = type;
6849
- const selected = setParserForSelectedString(query, joinedAs ? joinedAs + "." + value : value, getQueryAs(query), getValueKey);
6850
- q.select = selected ? [q.expr = new SelectItemExpression(query, selected, type)] : void 0;
6851
- } else if (isExpression(value)) {
6852
- type = value.result.value;
6853
- q.getColumn = type;
6854
- addParserForRawExpression(query, getValueKey, value);
6855
- q.select = [q.expr = value];
6856
- } else {
6857
- const selected = value;
6858
- q.getColumn = selected.q.getColumn;
6859
- if (q.getColumn) addColumnParserToQuery(q, getValueKey, q.getColumn);
6860
- q.select = selected ? [{ selectAs: { value: selected } }] : void 0;
6787
+ const selectAs = {};
6788
+ let column;
6789
+ const selected = processSelectAsArg(query, selectAs, getQueryAs(query), "v", value, void 0, returnType);
6790
+ if (selected !== false) {
6791
+ q.getColumn = column = selected;
6792
+ value = selectAs.v || value;
6861
6793
  }
6862
- return setQueryOperators(query, type?.operators || Operators.any);
6794
+ if (typeof value === "string") value = selectAs.v && new SelectItemExpression(query, selectAs.v, column);
6795
+ q.select = isExpression(value) ? [q.expr = value] : value ? [{ selectAs: { v: value } }] : void 0;
6796
+ return setQueryOperators(query, column?.operators || Operators.any);
6863
6797
  };
6864
6798
  function _queryGet(self, arg) {
6865
6799
  return _get(self, "valueOrThrow", arg);
@@ -7108,13 +7042,13 @@ const selectToSqlList = (ctx, table, query, quotedAs, hookSelect = query.hookSel
7108
7042
  (selected ??= {})[key] = `"${tableName}"`;
7109
7043
  (selectedAs ??= {})[key] = key;
7110
7044
  }
7111
- sql = tableColumnToSqlWithAs(ctx, table.q, item, tableName, key, key === "*" ? tableName : key, quotedAs, true, jsonList);
7045
+ sql = tableColumnToSql(ctx, query, query.selectShape, tableName, key, quotedAs, true, key === "*" ? tableName : key, jsonList);
7112
7046
  } else {
7113
7047
  if (hookSelect?.get(item)) {
7114
7048
  (selected ??= {})[item] = quotedAs;
7115
7049
  (selectedAs ??= {})[item] = item;
7116
7050
  }
7117
- sql = ownColumnToSqlWithAs(ctx, table.q, item, item, quotedAs, true, jsonList);
7051
+ sql = simpleColumnToSQL(ctx, query, query.selectShape, item, query.selectShape[item], quotedAs, true, item, jsonList);
7118
7052
  }
7119
7053
  }
7120
7054
  list.push(sql);
@@ -7126,7 +7060,9 @@ const selectToSqlList = (ctx, table, query, quotedAs, hookSelect = query.hookSel
7126
7060
  if (hookSelect) (selected ??= {})[as] = true;
7127
7061
  const value = obj[as];
7128
7062
  if (typeof value === "object") if (isExpression(value)) {
7129
- list.push(`${value.toSQL(ctx, quotedAs)} "${as}"`);
7063
+ let sql = value.toSQL(ctx, quotedAs);
7064
+ if (value.q.getColumn?.data.valueToArray) sql = `array[${sql}]`;
7065
+ list.push(`${sql} "${as}"`);
7130
7066
  if (jsonList) jsonList[as] = value.result.value;
7131
7067
  aliases?.push(as);
7132
7068
  } else if (delayedRelationSelect && isRelationQuery(value)) setMutativeQueriesSelectRelationsSqlState(delayedRelationSelect, as, value);
@@ -7136,13 +7072,14 @@ const selectToSqlList = (ctx, table, query, quotedAs, hookSelect = query.hookSel
7136
7072
  }
7137
7073
  else if (value) {
7138
7074
  if (hookSelect) (selectedAs ??= {})[value] = as;
7139
- list.push(columnToSqlWithAs(ctx, table.q, value, as, quotedAs, true, jsonList));
7075
+ list.push(columnToSql(ctx, table.q, table.q.selectShape, value, quotedAs, true, as, jsonList));
7140
7076
  aliases?.push(as);
7141
7077
  }
7142
7078
  }
7143
7079
  } else {
7144
7080
  ctx.selectedCount++;
7145
- const sql = item.toSQL(ctx, quotedAs);
7081
+ let sql = item.toSQL(ctx, quotedAs);
7082
+ if (item.q.getColumn?.data.valueToArray) sql = `array[${sql}]`;
7146
7083
  if (hookSelect && item instanceof SelectItemExpression && typeof item.item === "string" && item.item !== "*") {
7147
7084
  const i = item.item.indexOf(".");
7148
7085
  let key;
@@ -7150,7 +7087,7 @@ const selectToSqlList = (ctx, table, query, quotedAs, hookSelect = query.hookSel
7150
7087
  if (item.item.slice(0, i) === table.table) key = item.item.slice(i + 1);
7151
7088
  } else key = item.item;
7152
7089
  if (key) {
7153
- const column = item.q.shape[key];
7090
+ const column = item.q.selectShape[key];
7154
7091
  (selectedAs ??= {})[key] = column?.data.name || key;
7155
7092
  }
7156
7093
  }
@@ -7172,12 +7109,12 @@ const selectToSqlList = (ctx, table, query, quotedAs, hookSelect = query.hookSel
7172
7109
  quotedTable = `"${tableName}"`;
7173
7110
  columnName = select.slice(index + 1);
7174
7111
  col = table.q.joinedShapes?.[tableName]?.[columnName];
7175
- sql = selectedColumnToSql(ctx, table.q, table.q.shape, select, void 0);
7112
+ sql = columnToSql(ctx, table.q, table.shape, select, void 0, true, void 0, void 0, void 0, true);
7176
7113
  } else {
7177
7114
  quotedTable = quotedAs;
7178
7115
  columnName = select;
7179
- col = query.shape[select];
7180
- sql = selectedColumnToSql(ctx, table.q, query.shape, select, quotedAs);
7116
+ col = table.shape[select];
7117
+ sql = columnToSql(ctx, table.q, table.shape, select, quotedAs, true, void 0, void 0, void 0, true);
7181
7118
  }
7182
7119
  } else {
7183
7120
  columnName = column;
@@ -7222,15 +7159,15 @@ const internalSelectAllSql = (ctx, query, quotedAs, jsonList) => {
7222
7159
  jsonList[key] = getSelectedColumnData(column);
7223
7160
  }
7224
7161
  let columnsCount;
7225
- if (query.shape !== anyShape) {
7162
+ if (query.selectShape !== anyShape) {
7226
7163
  columnsCount = 0;
7227
- for (const key in query.shape) if (!query.shape[key].data.explicitSelect) columnsCount++;
7164
+ for (const key in query.selectShape) if (!query.selectShape[key].data.explicitSelect) columnsCount++;
7228
7165
  ctx.selectedCount += columnsCount;
7229
7166
  }
7230
7167
  return selectAllSql(query, quotedAs, columnsCount, ctx);
7231
7168
  };
7232
7169
  const selectAllSql = (q, quotedAs, columnsCount, ctx) => {
7233
- 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) ? [] : ["*"];
7170
+ 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) ? [] : ["*"];
7234
7171
  };
7235
7172
  const selectAllColumnToSql = (item, ctx, quotedAs, prefix) => {
7236
7173
  if (typeof item !== "string") return item(ctx, quotedAs);
@@ -7406,9 +7343,9 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
7406
7343
  ands.push(`NOT ${processAnds(arr, ctx, table, query, quotedAs, true)}`);
7407
7344
  } else if (key === "ON") if (Array.isArray(value)) {
7408
7345
  const item = value;
7409
- const leftColumn = columnToSql(ctx, query, query.shape, item[0], quotedAs);
7346
+ const leftColumn = columnToSqlNotSelect(ctx, query, query.selectShape, item[0], quotedAs);
7410
7347
  const leftPath = item[1];
7411
- const rightColumn = columnToSql(ctx, query, query.shape, item[2], quotedAs);
7348
+ const rightColumn = columnToSqlNotSelect(ctx, query, query.selectShape, item[2], quotedAs);
7412
7349
  const rightPath = item[3];
7413
7350
  ands.push(`jsonb_path_query_first(${leftColumn}, ${addValue(ctx.values, leftPath)}) = jsonb_path_query_first(${rightColumn}, ${addValue(ctx.values, rightPath)})`);
7414
7351
  } else {
@@ -7417,7 +7354,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
7417
7354
  const q = item.useOuterAliases ? {
7418
7355
  joinedShapes: query.joinedShapes,
7419
7356
  aliases: _getQueryOuterAliases(query),
7420
- shape: query.shape
7357
+ selectShape: query.selectShape
7421
7358
  } : query;
7422
7359
  ands.push(`${onColumnToSql(ctx, q, joinAs, item.from)} ${item.op || "="} ${onColumnToSql(ctx, q, joinAs, item.to)}`);
7423
7360
  }
@@ -7441,31 +7378,26 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
7441
7378
  ands.push(`${search.vectorSQL} @@ "${search.as}"`);
7442
7379
  } else if (typeof value === "object" && value && !(value instanceof Date) && !Array.isArray(value)) whereExprOrQuery(ctx, ands, query, key, value, quotedAs);
7443
7380
  else {
7444
- const column = columnToSql(ctx, query, query.shape, key, quotedAs);
7381
+ const column = columnToSqlNotSelect(ctx, query, query.selectShape, key, quotedAs);
7445
7382
  ands.push(`${column} ${value === null ? "IS NULL" : `= ${addValue(ctx.values, value)}`}`);
7446
7383
  }
7447
7384
  }
7448
7385
  };
7449
7386
  const whereExprOrQuery = (ctx, ands, query, key, value, quotedAs) => {
7450
- if (isExpression(value)) ands.push(`${columnToSql(ctx, query, query.shape, key, quotedAs)} = ${value.toSQL(ctx, quotedAs)}`);
7387
+ if (isExpression(value)) ands.push(`${columnToSqlNotSelect(ctx, query, query.selectShape, key, quotedAs)} = ${value.toSQL(ctx, quotedAs)}`);
7451
7388
  else {
7452
- let column = query.shape[key];
7453
- let quotedColumn;
7454
- if (column) quotedColumn = simpleExistingColumnToSQL(ctx, key, column, quotedAs);
7455
- else if (!column) {
7389
+ let column = query.selectShape[key];
7390
+ if (!column) {
7456
7391
  const index = key.indexOf(".");
7457
- if (index !== -1) {
7392
+ if (index === -1) column = query.joinedShapes?.[key]?.value;
7393
+ else if (index !== -1) {
7458
7394
  const table = key.slice(0, index);
7459
- const quoted = `"${table}"`;
7460
7395
  const name = key.slice(index + 1);
7461
- column = quotedAs === quoted ? query.shape[name] : query.joinedShapes?.[table]?.[name];
7462
- quotedColumn = simpleColumnToSQL(ctx, name, column, quoted);
7463
- } else {
7464
- column = query.joinedShapes?.[key]?.value;
7465
- quotedColumn = `"${key}"."${key}"`;
7396
+ column = quotedAs === `"${table}"` ? query.selectShape[name] : query.joinedShapes?.[table]?.[name];
7466
7397
  }
7467
- if (!column || !quotedColumn) throw new Error(`Unknown column ${key} provided to condition`);
7468
7398
  }
7399
+ if (!column) throw new Error(`Unknown column ${key} provided to condition`);
7400
+ const quotedColumn = columnToSqlNotSelect(ctx, query, query.selectShape, key, quotedAs);
7469
7401
  if (value instanceof ctx.qb.constructor) {
7470
7402
  const subQuerySql = moveMutativeQueryToCte(ctx, value);
7471
7403
  ands.push(`${quotedColumn} = (${subQuerySql})`);
@@ -7477,7 +7409,7 @@ const whereExprOrQuery = (ctx, ands, query, key, value, quotedAs) => {
7477
7409
  }
7478
7410
  }
7479
7411
  };
7480
- const onColumnToSql = (ctx, query, joinAs, column) => columnToSql(ctx, query, query.shape, column, joinAs);
7412
+ const onColumnToSql = (ctx, query, joinAs, column) => columnToSqlNotSelect(ctx, query, query.selectShape, column, joinAs);
7481
7413
  const getJoinItemSource = (joinItem) => {
7482
7414
  return typeof joinItem === "string" ? joinItem : getQueryAs(joinItem);
7483
7415
  };
@@ -7489,13 +7421,14 @@ const pushIn = (ctx, query, ands, quotedAs, arg) => {
7489
7421
  value = `(${value})`;
7490
7422
  } else if (isExpression(arg.values)) value = arg.values.toSQL(ctx, quotedAs);
7491
7423
  else value = `(${moveMutativeQueryToCte(ctx, arg.values)})`;
7492
- const columnsSql = arg.columns.map((column) => columnToSql(ctx, query, query.shape, column, quotedAs)).join(", ");
7424
+ const columnsSql = arg.columns.map((column) => columnToSqlNotSelect(ctx, query, query.selectShape, column, quotedAs)).join(", ");
7493
7425
  ands.push(`${multiple ? `(${columnsSql})` : columnsSql} IN ${value}`);
7494
7426
  };
7495
7427
  const MAX_BINDING_PARAMS = 65533;
7496
7428
  const makeInsertSql = (ctx, q, query, quotedAs, isSubSql) => {
7497
7429
  let { columns } = query;
7498
- const { shape, hookCreateSet } = query;
7430
+ const shape = q.shape;
7431
+ const { hookCreateSet } = query;
7499
7432
  const QueryClass = ctx.qb.constructor;
7500
7433
  let { insertFrom, queryColumnsCount, values } = query;
7501
7434
  let hookSetSql;
@@ -7532,7 +7465,7 @@ const makeInsertSql = (ctx, q, query, quotedAs, isSubSql) => {
7532
7465
  insertSql: `INSERT INTO ${quoteTableWithSchema(q)}${quotedColumns.length ? "(" + quotedColumns.join(", ") + ")" : ""}`
7533
7466
  };
7534
7467
  ctx.sql.push(null, null);
7535
- const hasOnConflictWhere = pushOnConflictSql(ctx, query, quotedAs, columns, quotedColumns, runtimeDefaultColumns);
7468
+ const hasOnConflictWhere = pushOnConflictSql(ctx, q, query, quotedAs, columns, quotedColumns, runtimeDefaultColumns);
7536
7469
  const upsert = query.type === "upsert";
7537
7470
  if (upsert || insertFrom && !isRelationQuery(q) || hasOnConflictWhere) pushWhereStatementSql(ctx, q, query, quotedAs);
7538
7471
  sqlState.relationSelectState = newMutativeQueriesSelectRelationsSqlState(q);
@@ -7599,9 +7532,9 @@ const makeInsertSql = (ctx, q, query, quotedAs, isSubSql) => {
7599
7532
  values: ctx.values
7600
7533
  };
7601
7534
  };
7602
- const pushOnConflictSql = (ctx, query, quotedAs, columns, quotedColumns, runtimeDefaultColumns) => {
7535
+ const pushOnConflictSql = (ctx, q, query, quotedAs, columns, quotedColumns, runtimeDefaultColumns) => {
7603
7536
  if (!query.onConflict) return false;
7604
- const { shape } = query;
7537
+ const shape = q.shape;
7605
7538
  ctx.sql.push("ON CONFLICT");
7606
7539
  const { target } = query.onConflict;
7607
7540
  if (target) if (typeof target === "string") ctx.sql.push(`("${shape[target]?.data.name || target}")`);
@@ -7814,7 +7747,7 @@ const pushUpdateSqlWithoutValuesJoinedAs = (ctx, query, q, quotedAs, isSubSql) =
7814
7747
  let updateManyValuesSql;
7815
7748
  if (q.updateMany) {
7816
7749
  for (const key of q.updateMany.primaryKeys) usedSetKeys.add(key);
7817
- updateManyValuesSql = makeUpdateManyValuesSql(ctx, query, q, q.updateMany, set, usedSetKeys, quotedAs);
7750
+ updateManyValuesSql = makeUpdateManyValuesSql(ctx, query, q.updateMany, set, usedSetKeys, quotedAs);
7818
7751
  }
7819
7752
  if (!set.length) pushSelectForEmptySet(ctx, query, q, quotedAs, from, isSubSql, updateManyValuesSql, relationSelectState);
7820
7753
  else {
@@ -7889,7 +7822,7 @@ const processData = (ctx, query, set, data, hookSet, usedSetKeys, quotedAs) => {
7889
7822
  };
7890
7823
  const applySet = (ctx, query, set, item, skipColumns, usedSetKeys, quotedAs) => {
7891
7824
  const QueryClass = ctx.qb.constructor;
7892
- const shape = query.q.shape;
7825
+ const shape = query.shape;
7893
7826
  for (const key in item) {
7894
7827
  if (usedSetKeys.has(key)) continue;
7895
7828
  usedSetKeys.add(key);
@@ -7905,12 +7838,12 @@ const processValue = (ctx, query, QueryClass, key, value, quotedAs) => {
7905
7838
  const subQuery = value;
7906
7839
  if (subQuery.q.subQuery === 1) return selectToSql(ctx, query, subQuery.q, quotedAs);
7907
7840
  return `(${moveMutativeQueryToCte(ctx, subQuery)})`;
7908
- } else if ("op" in value && "arg" in value) return `"${query.q.shape[key].data.name || key}" ${value.op} ${addValue(ctx.values, value.arg)}`;
7841
+ } else if ("op" in value && "arg" in value) return `"${query.shape[key].data.name || key}" ${value.op} ${addValue(ctx.values, value.arg)}`;
7909
7842
  }
7910
7843
  return addValue(ctx.values, value);
7911
7844
  };
7912
- const makeUpdateManyValuesSql = (ctx, query, q, updateMany, set, usedSetKeys, quotedAs) => {
7913
- const { shape } = q;
7845
+ const makeUpdateManyValuesSql = (ctx, query, updateMany, set, usedSetKeys, quotedAs) => {
7846
+ const shape = query.shape;
7914
7847
  const keysSet = /* @__PURE__ */ new Set();
7915
7848
  const valueRows = [];
7916
7849
  const quotedColumnNames = [];
@@ -8019,13 +7952,13 @@ const addOrder = (ctx, data, column, quotedAs, dir) => {
8019
7952
  const order = dir || (!search.order || search.order === true ? emptyObject : search.order);
8020
7953
  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"}`;
8021
7954
  }
8022
- return `${maybeSelectedColumnToSql(ctx, data, column, quotedAs)} ${dir || "ASC"}`;
7955
+ return `${columnToSqlNotSelect(ctx, data, data.selectShape, column, quotedAs, true)} ${dir || "ASC"}`;
8023
7956
  };
8024
7957
  const windowToSql = (ctx, data, window, quotedAs) => {
8025
7958
  if (typeof window === "string") return `"${window}"`;
8026
7959
  if (isExpression(window)) return `(${window.toSQL(ctx, quotedAs)})`;
8027
7960
  const sql = [];
8028
- 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)}`);
7961
+ 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)}`);
8029
7962
  if (window.order) sql.push(`ORDER BY ${orderByToSql(ctx, data, window.order, quotedAs)}`);
8030
7963
  return `(${sql.join(" ")})`;
8031
7964
  };
@@ -8046,12 +7979,6 @@ var FnExpression = class extends Expression {
8046
7979
  this.result = { value };
8047
7980
  this.q = query.q;
8048
7981
  this.q.expr = this;
8049
- Object.assign(query, value.operators);
8050
- query.q.returnType = "valueOrThrow";
8051
- query.q.returnsOne = true;
8052
- query.q.getColumn = value;
8053
- query.q.select = [this];
8054
- addColumnParserToQuery(query.q, getValueKey, value);
8055
7982
  }
8056
7983
  makeSQL(ctx, quotedAs) {
8057
7984
  const sql = [`${this.fn}(`];
@@ -8080,7 +8007,7 @@ var FnExpression = class extends Expression {
8080
8007
  const whereSql = whereToSql(ctx, this.query, {
8081
8008
  and: options.filter ? [options.filter] : void 0,
8082
8009
  or: options.filterOr?.map((item) => [item]),
8083
- shape: q.shape,
8010
+ selectShape: q.selectShape,
8084
8011
  joinedShapes: q.joinedShapes
8085
8012
  }, quotedAs);
8086
8013
  if (whereSql) sql.push(` FILTER (WHERE ${whereSql})`);
@@ -8091,16 +8018,22 @@ var FnExpression = class extends Expression {
8091
8018
  };
8092
8019
  const fnArgToSql = (ctx, data, arg, quotedAs) => {
8093
8020
  if (typeof arg === "string") {
8094
- if (arg.endsWith(".*") || data.valuesJoinedAs?.[arg]) return columnToSql(ctx, data, data.shape, arg, quotedAs);
8095
- return selectedColumnToSql(ctx, data, data.shape, arg, quotedAs);
8021
+ if (arg.endsWith(".*") || data.valuesJoinedAs?.[arg]) return columnToSql(ctx, data, data.selectShape, arg, quotedAs, void 0, void 0, void 0, void 0, true);
8022
+ return columnToSql(ctx, data, data.selectShape, arg, quotedAs, true, void 0, void 0, void 0, true);
8096
8023
  }
8097
8024
  return arg.toSQL(ctx, quotedAs);
8098
8025
  };
8099
8026
  function makeFnExpression(self, type, fn, args, options) {
8100
8027
  const q = extendQuery(self, type.operators);
8101
8028
  q.baseQuery.type = ExpressionTypeMethod.prototype.type;
8102
- new FnExpression(q, fn, args, options, type);
8029
+ q.q.select = [new FnExpression(q, fn, args, options, type)];
8030
+ q.q.getColumn = type;
8031
+ Object.assign(q, type.operators);
8032
+ setValueParserToQuery(q.q, type);
8033
+ q.q.returnType = "valueOrThrow";
8034
+ q.q.returnsOne = true;
8103
8035
  q.q.transform = void 0;
8036
+ q.q.batchParsers = void 0;
8104
8037
  return q;
8105
8038
  }
8106
8039
  const isSelectingCount = (q) => {
@@ -8109,17 +8042,14 @@ const isSelectingCount = (q) => {
8109
8042
  };
8110
8043
  const intNullable = new IntegerColumn(internalSchemaConfig).nullable().parse(parseInt);
8111
8044
  const floatNullable = new RealColumn(internalSchemaConfig).nullable().parse(parseFloat);
8112
- const booleanNullable = BooleanColumn.instance.nullable();
8045
+ const booleanNullable = BooleanColumn.instanceSkipValueToArray.nullable();
8113
8046
  const textNullable = TextColumn.instance.nullable();
8114
8047
  const jsonTextNullable = JSONTextColumn.instance.nullable();
8115
8048
  const xmlNullable = XMLColumn.instance.nullable();
8116
8049
  const stringAsNumberNullable = new NumberAsStringBaseColumn(internalSchemaConfig).nullable();
8050
+ intNullable.data.skipValueToArray = floatNullable.data.skipValueToArray = textNullable.data.skipValueToArray = jsonTextNullable.data.skipValueToArray = xmlNullable.data.skipValueToArray = stringAsNumberNullable.data.skipValueToArray = true;
8117
8051
  const numericResultColumn = (q, arg) => {
8118
- const query = q;
8119
- let column = (typeof arg === "string" ? _getSelectableColumn(query, arg) : arg.result.value) instanceof NumberBaseColumn ? floatNullable : stringAsNumberNullable;
8120
- const parse = typeof arg === "string" && query.q.parsers?.[arg];
8121
- if (parse) column = column.parse(parse);
8122
- return column;
8052
+ return (typeof arg === "string" ? _getSelectableColumn(q, arg) : arg.result.value) instanceof NumberBaseColumn ? floatNullable : stringAsNumberNullable;
8123
8053
  };
8124
8054
  var AggregateMethods = class {
8125
8055
  /**
@@ -8135,6 +8065,7 @@ var AggregateMethods = class {
8135
8065
  const q = _queryGetOptional(_clone(this), new RawSql("true"));
8136
8066
  q.q.notFoundDefault = false;
8137
8067
  q.q.coalesceValue = new RawSql("false");
8068
+ q.q.getColumn = BooleanColumn.instanceSkipValueToArray;
8138
8069
  return q;
8139
8070
  }
8140
8071
  /**
@@ -8896,7 +8827,7 @@ const createSelect = (q) => {
8896
8827
  * @param createHandlers - collects column `create` functions per column having it, and collects row indexes having a value for this column
8897
8828
  */
8898
8829
  const processCreateItem = (q, item, rowIndex, ctx, encoders, createHandlers) => {
8899
- const { shape } = q.q;
8830
+ const shape = q.shape;
8900
8831
  for (const key in item) {
8901
8832
  const column = shape[key];
8902
8833
  if (!column) continue;
@@ -9447,7 +9378,7 @@ var OnConflictQueryBuilder = class {
9447
9378
  const pushDistinctSql = (ctx, table, distinct, quotedAs) => {
9448
9379
  ctx.sql.push("DISTINCT");
9449
9380
  if (distinct.length) {
9450
- const columns = distinct?.map((item) => rawOrColumnToSql(ctx, table.q, item, quotedAs));
9381
+ const columns = distinct?.map((item) => rawOrColumnToSql(ctx, table.q, table.q.selectShape, item, quotedAs));
9451
9382
  ctx.sql.push(`ON (${columns?.join(", ") || ""})`);
9452
9383
  }
9453
9384
  };
@@ -9481,20 +9412,20 @@ const searchSourcesToSql = (ctx, data, sources, sql, quotedAs) => {
9481
9412
  return sql;
9482
9413
  };
9483
9414
  const getSearchLang = (ctx, data, source, quotedAs) => {
9484
- 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");
9415
+ 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");
9485
9416
  };
9486
9417
  const getSearchText = (ctx, data, source, quotedAs, forHeadline) => {
9487
9418
  let sql = source.textSQL;
9488
9419
  if (sql) return sql;
9489
- if ("in" in source) if (typeof source.in === "string") sql = columnToSql(ctx, data, data.shape, source.in, quotedAs);
9490
- else if (Array.isArray(source.in)) sql = `concat_ws(' ', ${source.in.map((column) => columnToSql(ctx, data, data.shape, column, quotedAs)).join(", ")})`;
9420
+ if ("in" in source) if (typeof source.in === "string") sql = columnToSqlNotSelect(ctx, data, data.selectShape, source.in, quotedAs);
9421
+ else if (Array.isArray(source.in)) sql = `concat_ws(' ', ${source.in.map((column) => columnToSqlNotSelect(ctx, data, data.selectShape, column, quotedAs)).join(", ")})`;
9491
9422
  else {
9492
9423
  sql = [];
9493
- for (const key in source.in) sql.push(columnToSql(ctx, data, data.shape, key, quotedAs));
9424
+ for (const key in source.in) sql.push(columnToSqlNotSelect(ctx, data, data.selectShape, key, quotedAs));
9494
9425
  }
9495
9426
  else if ("vector" in source) {
9496
9427
  if (forHeadline) throw new Error("Cannot use a search based on a vector column for a search headline");
9497
- sql = columnToSql(ctx, data, data.shape, source.vector, quotedAs);
9428
+ sql = columnToSqlNotSelect(ctx, data, data.selectShape, source.vector, quotedAs);
9498
9429
  } else if (typeof source.text === "string") sql = addValue(ctx.values, source.text);
9499
9430
  else sql = source.text.toSQL(ctx, quotedAs);
9500
9431
  return source.textSQL = sql;
@@ -9710,7 +9641,7 @@ const toSql = (table, type, topCtx, isSubSql, cteName, calledByThen, dontAddTabl
9710
9641
  if (isExpression(item)) return item.toSQL(ctx, quotedAs);
9711
9642
  else {
9712
9643
  const i = aliases.indexOf(item);
9713
- return i !== -1 ? i + 1 : columnToSql(ctx, table.q, table.shape, item, quotedAs);
9644
+ return i !== -1 ? i + 1 : columnToSqlNotSelect(ctx, table.q, table.shape, item, quotedAs);
9714
9645
  }
9715
9646
  });
9716
9647
  sql.push(`GROUP BY ${group.join(", ")}`);
@@ -10132,19 +10063,11 @@ const _joinLateral = (self, type, joinQuery, as, innerJoinLateral) => {
10132
10063
  }
10133
10064
  if (!existingValue) {
10134
10065
  const joinedAs = getQueryAs(query);
10135
- setObjectValueImmutable(joinQuery.q, "joinedShapes", joinedAs, query.q.shape);
10066
+ setObjectValueImmutable(joinQuery.q, "joinedShapes", joinedAs, query.q.selectShape);
10136
10067
  }
10137
10068
  const shape = getShapeFromSelect(joinQuery, true);
10138
10069
  setObjectValueImmutable(query.q, "joinedShapes", joinAs, shape);
10139
- const parsers = getQueryParsers(joinQuery);
10140
- if (joinValue) {
10141
- setObjectValueImmutable(query.q, "valuesJoinedAs", joinAs, joinValueAs);
10142
- if (parsers && getValueKey in parsers) {
10143
- const parse = parsers[getValueKey];
10144
- setParserToQuery(query.q, joinAs, parse);
10145
- parsers[joinAs] = parse;
10146
- }
10147
- }
10070
+ if (joinValue) setObjectValueImmutable(query.q, "valuesJoinedAs", joinAs, joinValueAs);
10148
10071
  setObjectValueImmutable(query.q, "joinedParsers", joinValueAs || joinAs, getQueryParsers(joinQuery));
10149
10072
  if (joinQuery.q.batchParsers) setObjectValueImmutable(query.q, "joinedBatchParsers", joinAs, joinQuery.q.batchParsers);
10150
10073
  if (joinValueAs) {
@@ -10904,15 +10827,12 @@ var OnMethods = class {
10904
10827
  const setSelectRelation = (q) => {
10905
10828
  q.selectRelation = true;
10906
10829
  };
10907
- const addParserForRawExpression = (q, key, raw) => {
10908
- if (raw.result.value) addColumnParserToQuery(q.q, key, raw.result.value);
10909
- };
10910
10830
  const addParsersForSelectJoined = (q, arg, as = arg) => {
10911
10831
  const parsers = q.q.joinedParsers?.[arg];
10912
10832
  if (parsers) setParserToQuery(q.q, as, (row) => parseRecord(parsers, row));
10913
10833
  const batchParsers = q.q.joinedBatchParsers?.[arg];
10914
10834
  if (batchParsers) pushQueryArrayImmutable(q, "batchParsers", batchParsers.map((x) => ({
10915
- path: [as, ...x.path],
10835
+ path: [{ key: as }, ...x.path],
10916
10836
  fn: x.fn
10917
10837
  })));
10918
10838
  };
@@ -10920,19 +10840,24 @@ const addParserForSelectItem = (query, as, key, arg, columnAlias, joinQuery) =>
10920
10840
  if (typeof arg === "object") {
10921
10841
  const { q } = arg;
10922
10842
  if (q.batchParsers) pushQueryArrayImmutable(query, "batchParsers", q.batchParsers.map((bp) => ({
10923
- path: [key, ...bp.path],
10843
+ path: [{
10844
+ key,
10845
+ returnType: q.returnType
10846
+ }, ...bp.path],
10924
10847
  fn: bp.fn
10925
10848
  })));
10926
10849
  const parsers = isExpression(arg) ? void 0 : getQueryParsers(arg);
10927
10850
  if (parsers || q.hookSelect || q.transform || q.returnType === "oneOrThrow" || q.returnType === "valueOrThrow" || q.returnType === "one" || q.returnType === "value") pushQueryValueImmutable(query, "batchParsers", {
10928
- path: [key],
10851
+ path: [{
10852
+ key,
10853
+ returnType: q.returnType
10854
+ }],
10929
10855
  fn: (path, queryResult) => {
10930
10856
  const { rows } = queryResult;
10931
10857
  const originalReturnType = q.returnType || "all";
10932
10858
  let returnType = originalReturnType;
10933
10859
  const { hookSelect } = q;
10934
10860
  const batches = [];
10935
- const last = path.length;
10936
10861
  if (returnType === "value" || returnType === "valueOrThrow") {
10937
10862
  if (hookSelect) batches.push = (item) => {
10938
10863
  if (!(key in item)) returnType = returnType === "value" ? "one" : "oneOrThrow";
@@ -10940,7 +10865,7 @@ const addParserForSelectItem = (query, as, key, arg, columnAlias, joinQuery) =>
10940
10865
  return batches.push(item);
10941
10866
  };
10942
10867
  }
10943
- collectNestedSelectBatches(batches, rows, path, last);
10868
+ collectNestedSelectBatches(batches, rows, path);
10944
10869
  switch (returnType) {
10945
10870
  case "all":
10946
10871
  if (parsers) for (const { data } of batches) for (const one of data) parseRecord(parsers, one);
@@ -10965,16 +10890,28 @@ const addParserForSelectItem = (query, as, key, arg, columnAlias, joinQuery) =>
10965
10890
  }
10966
10891
  case "value":
10967
10892
  case "valueOrThrow": {
10968
- const notNullable = !q.getColumn?.data.isNullable;
10969
- const parse = parsers?.[getValueKey];
10970
- if (parse) if (returnType === "value") for (const item of batches) item.parent[item.key] = item.data = item.data === null ? q.notFoundDefault : parse(item.data);
10893
+ const data = q.getColumn?.data;
10894
+ const notNullable = !data?.isNullable;
10895
+ const valueToArray = data?.valueToArray;
10896
+ const parse = getValueParser(parsers);
10897
+ 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;
10898
+ else for (const item of batches) item.parent[item.key] = item.data = item.data === null ? q.notFoundDefault : parse(item.data);
10899
+ else if (valueToArray) for (const item of batches) {
10900
+ if (!item.data) throw new NotFoundError(arg);
10901
+ item.parent[item.key] = item.data = item.data[0] === null ? null : parse(item.data[0]);
10902
+ }
10971
10903
  else for (const item of batches) {
10972
10904
  if (notNullable && item.data === null) throw new NotFoundError(arg);
10973
10905
  item.parent[item.key] = item.data = parse(item.data);
10974
10906
  }
10975
10907
  else if (returnType === "value") {
10976
- for (const item of batches) if (item.data === null) item.parent[item.key] = item.data = q.notFoundDefault;
10977
- } else if (notNullable) {
10908
+ if (valueToArray) for (const item of batches) item.parent[item.key] = item.data = item.data ? item.data[0] : q.notFoundDefault;
10909
+ else for (const item of batches) if (item.data === void 0) item.parent[item.key] = item.data = q.notFoundDefault;
10910
+ } else if (valueToArray) for (const item of batches) {
10911
+ if (!item.data) throw new NotFoundError(arg);
10912
+ item.parent[item.key] = item.data = item.data[0];
10913
+ }
10914
+ else if (notNullable) {
10978
10915
  for (const { data } of batches) if (data === null) throw new NotFoundError(arg);
10979
10916
  }
10980
10917
  if (hookSelect) for (const batch of batches) batch.data = [batch.data];
@@ -11012,59 +10949,52 @@ const addParserForSelectItem = (query, as, key, arg, columnAlias, joinQuery) =>
11012
10949
  }
11013
10950
  return arg;
11014
10951
  }
11015
- return setParserForSelectedString(query, arg, as, key, columnAlias);
10952
+ const joinedAs = query.q.valuesJoinedAs?.[arg];
10953
+ return setParserForSelectedString(query, joinedAs ? joinedAs + "." + arg : arg, as, key, columnAlias);
11016
10954
  };
11017
- const collectNestedSelectBatches = (batches, rows, path, last) => {
11018
- const stack = rows.map((row) => ({
11019
- data: row,
11020
- parent: row,
11021
- i: 0,
11022
- key: path[0]
11023
- }));
11024
- while (stack.length > 0) {
11025
- const item = stack.pop();
11026
- const { i } = item;
11027
- if (i === last) {
11028
- batches.push(item);
11029
- continue;
11030
- }
11031
- const { data } = item;
11032
- const key = path[i];
11033
- if (Array.isArray(data)) for (let key = 0; key < data.length; key++) stack.push({
11034
- data: data[key],
11035
- parent: data,
11036
- key,
11037
- i
11038
- });
11039
- else if (data && typeof data === "object") stack.push({
11040
- data: data[key],
11041
- parent: data,
11042
- key,
11043
- i: i + 1
11044
- });
10955
+ const collectNestedSelectBatches = (batches, rows, path) => {
10956
+ const last = path.length - 1;
10957
+ const { key, returnType } = path[0];
10958
+ for (const row of rows) processNestedSelectPathEntry(batches, path, key, returnType, 0, last, row);
10959
+ };
10960
+ const processNestedSelectPathEntry = (batches, path, thisKey, thisReturnType, i, last, parent) => {
10961
+ const data = parent[thisKey];
10962
+ if (i === last) batches.push({
10963
+ data,
10964
+ parent,
10965
+ key: thisKey
10966
+ });
10967
+ else {
10968
+ const { key, returnType } = path[++i];
10969
+ if (!thisReturnType || thisReturnType === "all") for (const row of data) processNestedSelectPathEntry(batches, path, key, returnType, i, last, row);
10970
+ else processNestedSelectPathEntry(batches, path, key, returnType, i, last, data);
11045
10971
  }
11046
10972
  };
11047
10973
  const emptyArrSQL = new RawSql("'[]'");
11048
10974
  const processSelectArg = (q, as, arg, columnAs) => {
11049
- if (typeof arg === "string") return setParserForSelectedString(q, arg, as, columnAs);
10975
+ const query = q;
10976
+ if (typeof arg === "string") return setParserForSelectedString(query, arg, as, columnAs);
11050
10977
  const selectAs = {};
10978
+ const selectShape = query.q.selectShape = { ...query.q.selectShape };
11051
10979
  for (const key in arg) {
11052
- const item = processSelectAsArg(q, as, key, arg[key]);
11053
- if (item === false) return false;
11054
- selectAs[key] = item;
10980
+ const item = processSelectAsArg(q, selectAs, as, key, arg[key], key);
10981
+ if (item) selectShape[key] = item;
10982
+ else if (item === false) return false;
11055
10983
  }
11056
10984
  return { selectAs };
11057
10985
  };
11058
- const processSelectAsArg = (q, as, key, arg) => {
10986
+ const processSelectAsArg = (q, selectAs, as, key, arg, columnAlias, outerReturnType) => {
11059
10987
  const query = q;
11060
10988
  let value = arg;
11061
10989
  let joinQuery;
10990
+ let column;
11062
10991
  if (typeof value === "function") {
11063
10992
  value = resolveSubQueryCallback(q, value);
11064
10993
  if (isQueryNone(value)) {
11065
10994
  if (value.q.innerJoinLateral) return false;
11066
10995
  }
11067
- if (!isExpression(value)) {
10996
+ if (isExpression(value)) column = value.result.value;
10997
+ else {
11068
10998
  if (isRelationQuery(value) && value.q.subQuery !== 1) {
11069
10999
  joinQuery = true;
11070
11000
  setSelectRelation(query.q);
@@ -11085,10 +11015,27 @@ const processSelectAsArg = (q, as, key, arg) => {
11085
11015
  const as = _joinLateral(q, innerJoinLateral || query.q.returnType === "valueOrThrow" ? "JOIN" : "LEFT JOIN", subQuery, key, innerJoinLateral && returnType !== "one" && returnType !== "oneOrThrow");
11086
11016
  if (as) value.q.joinedForSelect = _copyQueryAliasToQuery(value, q, as);
11087
11017
  }
11018
+ if (value.q.getColumn?.data.skipValueToArray) value.q.notFoundDefault ??= null;
11019
+ else if (!value.q.type && (value.q.returnType === "value" || value.q.returnType === "valueOrThrow")) {
11020
+ const column = Object.create(value.q.getColumn || UnknownColumn.instance);
11021
+ column.data = {
11022
+ ...column.data,
11023
+ name: void 0,
11024
+ valueToArray: true
11025
+ };
11026
+ value.q.getColumn = column;
11027
+ if (value.q.expr) value.q.expr.q.getColumn = column;
11028
+ }
11029
+ if (outerReturnType === "value" && value.q.returnType === "valueOrThrow") value.q.returnType = "value";
11030
+ column = value.q.getColumn;
11088
11031
  value = prepareSubQueryForSql(q, value);
11089
11032
  }
11090
- }
11091
- return addParserForSelectItem(query, as, key, value, key, joinQuery);
11033
+ } else if (typeof value === "string") {
11034
+ const joinedAs = query.q.valuesJoinedAs?.[value];
11035
+ column = joinedAs ? query.q.joinedShapes?.[joinedAs]?.value : _getSelectableColumn(query, value);
11036
+ } else column = value.result.value;
11037
+ selectAs[key] = addParserForSelectItem(query, as, key, value, columnAlias, joinQuery);
11038
+ return column;
11092
11039
  };
11093
11040
  const setParserForSelectedString = (query, arg, as, columnAs, columnAlias) => {
11094
11041
  const { q } = query;
@@ -11106,7 +11053,7 @@ const setParserForSelectedString = (query, arg, as, columnAs, columnAlias) => {
11106
11053
  const batchParsers = q.joinedBatchParsers?.[table];
11107
11054
  if (batchParsers) {
11108
11055
  let cloned = false;
11109
- for (const bp of batchParsers) if (bp.path[0] === column) {
11056
+ for (const bp of batchParsers) if (bp.path[0].key === column) {
11110
11057
  if (!cloned) {
11111
11058
  q.batchParsers = [...q.batchParsers || []];
11112
11059
  cloned = true;
@@ -11144,7 +11091,7 @@ const selectColumn = (query, q, key, columnAs, columnAlias) => {
11144
11091
  };
11145
11092
  const getShapeFromSelect = (q, isSubQuery) => {
11146
11093
  const query = q.q;
11147
- const { shape } = query;
11094
+ const { selectShape: shape } = query;
11148
11095
  let select;
11149
11096
  if (query.selectedComputeds) {
11150
11097
  select = query.select ? [...query.select] : [];
@@ -11621,14 +11568,14 @@ var RefExpression = class extends Expression {
11621
11568
  makeSQL(ctx) {
11622
11569
  const q = this.q;
11623
11570
  const as = q.as || this.table;
11624
- return columnToSql(ctx, q, q.shape, this.ref, as && `"${as}"`);
11571
+ return columnToSqlNotSelect(ctx, q, q.selectShape, this.ref, as && `"${as}"`);
11625
11572
  }
11626
11573
  };
11627
11574
  const _queryUpdateMany = (self, primaryKeys, data, strict) => {
11628
11575
  const query = self;
11629
11576
  throwIfReadOnly(query);
11630
11577
  const { q } = query;
11631
- const { shape } = q;
11578
+ const shape = query.shape;
11632
11579
  q.type = "update";
11633
11580
  setUpdateReturning(q);
11634
11581
  if (!data.length) return _queryNone(query);
@@ -11684,7 +11631,7 @@ const _queryUpdate = (updateSelf, arg) => {
11684
11631
  q.type = "update";
11685
11632
  const set = { ...arg };
11686
11633
  pushQueryValueImmutable(query, "updateData", set);
11687
- const { shape } = q;
11634
+ const shape = query.shape;
11688
11635
  let selectQuery;
11689
11636
  for (const key in arg) {
11690
11637
  const item = shape[key];
@@ -12357,7 +12304,7 @@ var ColumnRefExpression = class extends Expression {
12357
12304
  Object.assign(this, value.operators);
12358
12305
  }
12359
12306
  makeSQL(ctx, quotedAs) {
12360
- return simpleExistingColumnToSQL(ctx, this.name, this.result.value, quotedAs);
12307
+ return simpleColumnToSQL(ctx, emptyObject, emptyObject, this.name, this.result.value, quotedAs, void 0, void 0, void 0, void 0, true);
12361
12308
  }
12362
12309
  };
12363
12310
  var OrExpression = class extends Expression {
@@ -12444,16 +12391,16 @@ var QueryExpressions = class {
12444
12391
  */
12445
12392
  ref(arg) {
12446
12393
  const q = _clone(this);
12447
- const { shape } = q.q;
12394
+ const { selectShape } = q.q;
12448
12395
  let column;
12449
12396
  const index = arg.indexOf(".");
12450
12397
  if (index !== -1) {
12451
12398
  const as = q.q.as || q.table;
12452
12399
  const table = getFullColumnTable(q, arg, index, as);
12453
12400
  const col = arg.slice(index + 1);
12454
- if (table === as) column = shape[col];
12401
+ if (table === as) column = selectShape[col];
12455
12402
  else column = q.q.joinedShapes?.[table][col];
12456
- } else column = shape[arg];
12403
+ } else column = selectShape[arg];
12457
12404
  return new RefExpression(column || UnknownColumn.instance, q, arg);
12458
12405
  }
12459
12406
  val(value) {
@@ -12496,7 +12443,7 @@ var QueryExpressions = class {
12496
12443
  * @param options
12497
12444
  */
12498
12445
  fn(fn, args, options) {
12499
- return makeFnExpression(this, emptyObject, fn, args, options);
12446
+ return makeFnExpression(this, UnknownColumn.instance, fn, args, options);
12500
12447
  }
12501
12448
  or(...args) {
12502
12449
  return new OrExpression(args);
@@ -12509,7 +12456,7 @@ const _appendQueryOnUpsertCreate = (main, append, asFn) => {
12509
12456
  return pushQueryValueImmutable(pushQueryValueImmutable(main, "upsertCreateAppendQueries", prepareSubQueryForSql(main, append)), "upsertCreateAsFns", asFn);
12510
12457
  };
12511
12458
  const mergableObjects = new Set([
12512
- "shape",
12459
+ "selectShape",
12513
12460
  "withShapes",
12514
12461
  "defaultParsers",
12515
12462
  "parsers",
@@ -12713,7 +12660,7 @@ var Headline = class extends Expression {
12713
12660
  const { source, params } = this;
12714
12661
  const q = this.q;
12715
12662
  const lang = getSearchLang(ctx, q, source, quotedAs);
12716
- 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);
12663
+ 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);
12717
12664
  const options = params?.options ? `, ${params.options instanceof Expression ? params.options.toSQL(ctx, quotedAs) : addValue(ctx.values, params.options)}` : "";
12718
12665
  return `ts_headline(${lang}, ${text}, "${source.as}"${options})`;
12719
12666
  }
@@ -13039,10 +12986,12 @@ var QueryPluck = class {
13039
12986
  const q = _clone(this);
13040
12987
  q.q.returnType = "pluck";
13041
12988
  let selected;
13042
- if (typeof select === "function") {
13043
- const item = processSelectAsArg(q, q.q.as || q.table, "pluck", select);
13044
- if (item !== false) selected = isExpression(item) ? item : { selectAs: { pluck: item } };
13045
- } else selected = addParserForSelectItem(q, q.q.as || q.table, "pluck", select);
12989
+ const selectAs = {};
12990
+ const item = processSelectAsArg(q, selectAs, q.q.as || q.table, "pluck", select, void 0, "value");
12991
+ if (item !== false) {
12992
+ q.q.getColumn = item;
12993
+ selected = typeof selectAs.pluck === "object" && !isExpression(selectAs.pluck) ? { selectAs } : selectAs.pluck;
12994
+ }
13046
12995
  q.q.select = selected ? [selected] : void 0;
13047
12996
  return q;
13048
12997
  }
@@ -13980,7 +13929,7 @@ var Db = class extends QueryMethods {
13980
13929
  };
13981
13930
  this.q = {
13982
13931
  adapter: adapterNotInTransaction,
13983
- shape,
13932
+ selectShape: shape,
13984
13933
  handleResult,
13985
13934
  logger,
13986
13935
  log: logParamToLogObject(logger, options.log),
@@ -14318,7 +14267,7 @@ const makeColumnInfoSql = (query, column) => {
14318
14267
  const values = [];
14319
14268
  const schema = getQuerySchema(query);
14320
14269
  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()"}`;
14321
- if (column) text += ` AND column_name = ${addValue(values, query.q.shape[column]?.data.name || column)}`;
14270
+ if (column) text += ` AND column_name = ${addValue(values, query.shape[column]?.data.name || column)}`;
14322
14271
  return {
14323
14272
  text,
14324
14273
  values
@@ -14374,7 +14323,7 @@ const makeCopySql = (table, copy) => {
14374
14323
  const ctx = newToSqlCtx(table);
14375
14324
  const { q } = table;
14376
14325
  const quotedAs = `"${q.as || table.table}"`;
14377
- const columns = copy.columns ? `(${copy.columns.map((item) => `"${q.shape[item]?.data.name || item}"`).join(", ")})` : "";
14326
+ const columns = copy.columns ? `(${copy.columns.map((item) => `"${table.shape[item]?.data.name || item}"`).join(", ")})` : "";
14378
14327
  const target = "from" in copy ? copy.from : copy.to;
14379
14328
  const quotedTable = quoteTableWithSchema(table);
14380
14329
  ctx.sql.push(`COPY ${quotedTable}${columns} ${"from" in copy ? "FROM" : "TO"} ${typeof target === "string" ? escapeString(target) : `PROGRAM ${escapeString(target.program)}`}`);