ts-prorm-orm 1.1.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.
Files changed (310) hide show
  1. package/CHANGELOG.md +1111 -0
  2. package/LICENSE +21 -0
  3. package/README.md +573 -0
  4. package/dist/audit/history-query.js +180 -0
  5. package/dist/audit/index.js +23 -0
  6. package/dist/audit/logger.js +236 -0
  7. package/dist/cache/cache-manager.js +84 -0
  8. package/dist/cache/index.js +16 -0
  9. package/dist/cache/redis-cluster-cache.js +557 -0
  10. package/dist/cli.js +2200 -0
  11. package/dist/compliance/audit-trail.js +68 -0
  12. package/dist/compliance/backup-verification.js +685 -0
  13. package/dist/compliance/breach-detector.js +505 -0
  14. package/dist/compliance/consent-record.js +227 -0
  15. package/dist/compliance/consent-versioning.js +331 -0
  16. package/dist/compliance/cross-border-log.js +530 -0
  17. package/dist/compliance/data-classifier.js +258 -0
  18. package/dist/compliance/data-lineage.js +565 -0
  19. package/dist/compliance/data-masker.js +303 -0
  20. package/dist/compliance/data-portability.js +265 -0
  21. package/dist/compliance/data-retention.js +195 -0
  22. package/dist/compliance/dsar-workflow.js +342 -0
  23. package/dist/compliance/field-encryption.js +223 -0
  24. package/dist/compliance/immutable-record.js +148 -0
  25. package/dist/compliance/index.js +260 -0
  26. package/dist/compliance/privacy-impact-assessment.js +364 -0
  27. package/dist/compliance/pseudonymization.js +269 -0
  28. package/dist/compliance/query-firewall.js +1182 -0
  29. package/dist/compliance/rate-limiter.js +580 -0
  30. package/dist/compliance/right-to-erasure.js +117 -0
  31. package/dist/compliance/row-level-security.js +246 -0
  32. package/dist/compliance/security-decorator.js +574 -0
  33. package/dist/compliance/security-monitor.js +525 -0
  34. package/dist/compliance/sensitive-data-discovery.js +476 -0
  35. package/dist/compliance/session-isolation.js +472 -0
  36. package/dist/compliance/tls-enforcer.js +108 -0
  37. package/dist/compliance/worm-storage.js +712 -0
  38. package/dist/connection-manager.js +198 -0
  39. package/dist/connection-pool.js +519 -0
  40. package/dist/decorators/audit.js +136 -0
  41. package/dist/decorators/belongs-to-many.js +115 -0
  42. package/dist/decorators/belongs-to.js +115 -0
  43. package/dist/decorators/check.js +435 -0
  44. package/dist/decorators/collate.js +329 -0
  45. package/dist/decorators/comment.js +205 -0
  46. package/dist/decorators/database-settings.js +236 -0
  47. package/dist/decorators/default.js +244 -0
  48. package/dist/decorators/encryption.js +235 -0
  49. package/dist/decorators/engine.js +97 -0
  50. package/dist/decorators/fk-constraints.js +594 -0
  51. package/dist/decorators/foreign-table.js +136 -0
  52. package/dist/decorators/generated.js +274 -0
  53. package/dist/decorators/has-many.js +127 -0
  54. package/dist/decorators/has-one.js +116 -0
  55. package/dist/decorators/hstore.js +129 -0
  56. package/dist/decorators/index.js +355 -0
  57. package/dist/decorators/json-column.js +83 -0
  58. package/dist/decorators/jsonb.js +101 -0
  59. package/dist/decorators/orm-decorators.js +425 -0
  60. package/dist/decorators/permissions.js +294 -0
  61. package/dist/decorators/procedure.js +210 -0
  62. package/dist/decorators/query-options.js +556 -0
  63. package/dist/decorators/range.js +167 -0
  64. package/dist/decorators/set-column.js +83 -0
  65. package/dist/decorators/spatial.js +114 -0
  66. package/dist/decorators/storage.js +580 -0
  67. package/dist/decorators/timezone.js +512 -0
  68. package/dist/decorators/trigger.js +90 -0
  69. package/dist/decorators/uuid.js +135 -0
  70. package/dist/decorators/view.js +258 -0
  71. package/dist/diagrams/chen-diagram.js +354 -0
  72. package/dist/diagrams/class-diagram.js +384 -0
  73. package/dist/diagrams/dependency-diagram.js +432 -0
  74. package/dist/diagrams/er-diagram.js +605 -0
  75. package/dist/diagrams/flow-diagram.js +394 -0
  76. package/dist/diagrams/gantt-diagram.js +411 -0
  77. package/dist/diagrams/index-diagram.js +353 -0
  78. package/dist/diagrams/index.js +184 -0
  79. package/dist/diagrams/migration-diagram.js +316 -0
  80. package/dist/diagrams/model-diagram.js +616 -0
  81. package/dist/diagrams/package-diagram.js +376 -0
  82. package/dist/diagrams/palette.js +85 -0
  83. package/dist/diagrams/relational-diagram.js +455 -0
  84. package/dist/diagrams/schemadoc-diagram.js +309 -0
  85. package/dist/diagrams/sequence-diagram.js +307 -0
  86. package/dist/diagrams/state-diagram.js +344 -0
  87. package/dist/diagrams/svg-dom.js +111 -0
  88. package/dist/diagrams/tree-diagram.js +250 -0
  89. package/dist/dialects/clickhouse/index.js +1742 -0
  90. package/dist/dialects/cockroachdb/index.js +4677 -0
  91. package/dist/dialects/cratedb/index.js +441 -0
  92. package/dist/dialects/databricks/index.js +517 -0
  93. package/dist/dialects/db2/index.js +2225 -0
  94. package/dist/dialects/dialect.js +720 -0
  95. package/dist/dialects/duckdb/index.js +2014 -0
  96. package/dist/dialects/exasol/index.js +357 -0
  97. package/dist/dialects/firebird/index.js +495 -0
  98. package/dist/dialects/greenplum/index.js +457 -0
  99. package/dist/dialects/hana/index.js +1741 -0
  100. package/dist/dialects/mariadb/index.js +3590 -0
  101. package/dist/dialects/mssql/index.js +2296 -0
  102. package/dist/dialects/mysql/index.js +4058 -0
  103. package/dist/dialects/oracle/index.js +2999 -0
  104. package/dist/dialects/postgres/index.js +5319 -0
  105. package/dist/dialects/query-stream-helper.js +152 -0
  106. package/dist/dialects/questdb/index.js +433 -0
  107. package/dist/dialects/redshift/index.js +2277 -0
  108. package/dist/dialects/singlestore/index.js +354 -0
  109. package/dist/dialects/snowflake/index.js +2082 -0
  110. package/dist/dialects/spanner/index.js +1768 -0
  111. package/dist/dialects/sqlite/index.js +3382 -0
  112. package/dist/dialects/tidb/index.js +377 -0
  113. package/dist/dialects/timescaledb/index.js +164 -0
  114. package/dist/dialects/trino/index.js +420 -0
  115. package/dist/dialects/turso/index.js +227 -0
  116. package/dist/dialects/vertica/index.js +317 -0
  117. package/dist/dialects/yugabytedb/index.js +424 -0
  118. package/dist/errors/index.js +472 -0
  119. package/dist/errors/utils.js +340 -0
  120. package/dist/errors.js +21 -0
  121. package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
  122. package/dist/extensions/catalog/mssql-features.js +147 -0
  123. package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
  124. package/dist/extensions/catalog/oracle-db2-features.js +196 -0
  125. package/dist/extensions/catalog/postgres-extensions.js +516 -0
  126. package/dist/extensions/index.js +71 -0
  127. package/dist/extensions/types.js +13 -0
  128. package/dist/foreign-data.js +173 -0
  129. package/dist/hooks/hooks-manager.js +350 -0
  130. package/dist/hooks/index.js +37 -0
  131. package/dist/index.js +463 -0
  132. package/dist/logging.js +335 -0
  133. package/dist/migrations/index.js +40 -0
  134. package/dist/migrations/migration.js +196 -0
  135. package/dist/migrations/migrator.js +411 -0
  136. package/dist/migrations/prormmigration.js +275 -0
  137. package/dist/migrations/query-interface.js +435 -0
  138. package/dist/migrations/seeder.js +353 -0
  139. package/dist/models/associations.js +852 -0
  140. package/dist/models/constraints.js +288 -0
  141. package/dist/models/data-types.js +2518 -0
  142. package/dist/models/decorators.js +445 -0
  143. package/dist/models/index.js +33 -0
  144. package/dist/models/indexes.js +531 -0
  145. package/dist/models/methods.js +382 -0
  146. package/dist/models/model-manager.js +103 -0
  147. package/dist/models/model.js +5349 -0
  148. package/dist/models/operators.js +67 -0
  149. package/dist/models/scopes.js +189 -0
  150. package/dist/models/typescript-types.js +26 -0
  151. package/dist/nosql/aerospike/index.js +205 -0
  152. package/dist/nosql/allegrograph/index.js +169 -0
  153. package/dist/nosql/arangodb/index.js +364 -0
  154. package/dist/nosql/azure-blob/index.js +206 -0
  155. package/dist/nosql/beanstalkd/index.js +231 -0
  156. package/dist/nosql/beequeue/index.js +210 -0
  157. package/dist/nosql/bigchaindb/index.js +195 -0
  158. package/dist/nosql/bigtable/index.js +224 -0
  159. package/dist/nosql/blazegraph/index.js +173 -0
  160. package/dist/nosql/bullmq/index.js +191 -0
  161. package/dist/nosql/cassandra/index.js +174 -0
  162. package/dist/nosql/chroma/index.js +190 -0
  163. package/dist/nosql/cloudflare-kv/index.js +220 -0
  164. package/dist/nosql/coherence/index.js +200 -0
  165. package/dist/nosql/cosmosdb/index.js +157 -0
  166. package/dist/nosql/couchbase/index.js +213 -0
  167. package/dist/nosql/dax/index.js +212 -0
  168. package/dist/nosql/deno-kv/index.js +206 -0
  169. package/dist/nosql/dgraph/index.js +171 -0
  170. package/dist/nosql/doris/index.js +169 -0
  171. package/dist/nosql/druid/index.js +162 -0
  172. package/dist/nosql/dynamodb/index.js +937 -0
  173. package/dist/nosql/elasticsearch/index.js +377 -0
  174. package/dist/nosql/etcd/index.js +502 -0
  175. package/dist/nosql/eventhubs/index.js +213 -0
  176. package/dist/nosql/eventstore/index.js +254 -0
  177. package/dist/nosql/faunadb/index.js +188 -0
  178. package/dist/nosql/firestore/index.js +177 -0
  179. package/dist/nosql/fluree/index.js +148 -0
  180. package/dist/nosql/fuseki/index.js +170 -0
  181. package/dist/nosql/gcs/index.js +172 -0
  182. package/dist/nosql/gearman/index.js +160 -0
  183. package/dist/nosql/geode/index.js +196 -0
  184. package/dist/nosql/graphdb/index.js +169 -0
  185. package/dist/nosql/graylog/index.js +188 -0
  186. package/dist/nosql/gridgain/index.js +171 -0
  187. package/dist/nosql/hazelcast/index.js +162 -0
  188. package/dist/nosql/hbase/index.js +230 -0
  189. package/dist/nosql/ignite/index.js +173 -0
  190. package/dist/nosql/immudb/index.js +184 -0
  191. package/dist/nosql/index.js +232 -0
  192. package/dist/nosql/infinispan/index.js +200 -0
  193. package/dist/nosql/influxdb/index.js +0 -0
  194. package/dist/nosql/kafka/index.js +234 -0
  195. package/dist/nosql/keyspaces/index.js +189 -0
  196. package/dist/nosql/kinesis/index.js +253 -0
  197. package/dist/nosql/leveldb/index.js +153 -0
  198. package/dist/nosql/lmdb/index.js +160 -0
  199. package/dist/nosql/loki/index.js +201 -0
  200. package/dist/nosql/marklogic/index.js +204 -0
  201. package/dist/nosql/materialize/index.js +145 -0
  202. package/dist/nosql/meilisearch/index.js +154 -0
  203. package/dist/nosql/memcached/index.js +223 -0
  204. package/dist/nosql/milvus/index.js +410 -0
  205. package/dist/nosql/minio/index.js +265 -0
  206. package/dist/nosql/momento/index.js +179 -0
  207. package/dist/nosql/mongodb/index.js +461 -0
  208. package/dist/nosql/nats/index.js +247 -0
  209. package/dist/nosql/nedb/index.js +164 -0
  210. package/dist/nosql/neo4j/index.js +450 -0
  211. package/dist/nosql/neptune/index.js +470 -0
  212. package/dist/nosql/nsq/index.js +200 -0
  213. package/dist/nosql/opensearch/index.js +186 -0
  214. package/dist/nosql/orientdb/index.js +175 -0
  215. package/dist/nosql/papertrail/index.js +200 -0
  216. package/dist/nosql/pinecone/index.js +0 -0
  217. package/dist/nosql/pinot/index.js +133 -0
  218. package/dist/nosql/pouchdb/index.js +172 -0
  219. package/dist/nosql/prometheus/index.js +174 -0
  220. package/dist/nosql/provendb/index.js +147 -0
  221. package/dist/nosql/pubsub/index.js +187 -0
  222. package/dist/nosql/pulsar/index.js +232 -0
  223. package/dist/nosql/qdrant/index.js +295 -0
  224. package/dist/nosql/qldb/index.js +192 -0
  225. package/dist/nosql/r2/index.js +281 -0
  226. package/dist/nosql/rabbitmq/index.js +237 -0
  227. package/dist/nosql/ravendb/index.js +175 -0
  228. package/dist/nosql/redis/index.js +607 -0
  229. package/dist/nosql/redpanda/index.js +237 -0
  230. package/dist/nosql/resque/index.js +203 -0
  231. package/dist/nosql/rethinkdb/index.js +232 -0
  232. package/dist/nosql/rocksdb/index.js +152 -0
  233. package/dist/nosql/rockset/index.js +126 -0
  234. package/dist/nosql/s3/index.js +298 -0
  235. package/dist/nosql/scylladb/index.js +178 -0
  236. package/dist/nosql/signoz/index.js +227 -0
  237. package/dist/nosql/sns/index.js +201 -0
  238. package/dist/nosql/solr/index.js +231 -0
  239. package/dist/nosql/splunk/index.js +227 -0
  240. package/dist/nosql/sqs/index.js +246 -0
  241. package/dist/nosql/stardog/index.js +169 -0
  242. package/dist/nosql/starrocks/index.js +170 -0
  243. package/dist/nosql/store.js +2 -0
  244. package/dist/nosql/sumologic/index.js +213 -0
  245. package/dist/nosql/surrealdb/index.js +179 -0
  246. package/dist/nosql/terminusdb/index.js +151 -0
  247. package/dist/nosql/tigergraph/index.js +469 -0
  248. package/dist/nosql/typesense/index.js +148 -0
  249. package/dist/nosql/unqlite/index.js +157 -0
  250. package/dist/nosql/upstash/index.js +167 -0
  251. package/dist/nosql/vercel-kv/index.js +166 -0
  252. package/dist/nosql/victoriametrics/index.js +213 -0
  253. package/dist/nosql/virtuoso/index.js +169 -0
  254. package/dist/nosql/weaviate/index.js +276 -0
  255. package/dist/operators/index.js +108 -0
  256. package/dist/operators.js +2690 -0
  257. package/dist/prisma-migrate/index.js +38 -0
  258. package/dist/prisma-migrate/migration-generator.js +125 -0
  259. package/dist/prisma-migrate/model-generator.js +172 -0
  260. package/dist/prisma-migrate/relations.js +100 -0
  261. package/dist/prisma-migrate/schema-parser.js +167 -0
  262. package/dist/prisma-migrate/type-mapper.js +40 -0
  263. package/dist/prorm.js +6832 -0
  264. package/dist/query-builders/cte-builder.js +80 -0
  265. package/dist/query-builders/functions/aggregate.js +390 -0
  266. package/dist/query-builders/functions/conditional.js +503 -0
  267. package/dist/query-builders/functions/datetime.js +695 -0
  268. package/dist/query-builders/functions/fulltext.js +439 -0
  269. package/dist/query-builders/functions/index.js +93 -0
  270. package/dist/query-builders/functions/json.js +427 -0
  271. package/dist/query-builders/functions/math.js +399 -0
  272. package/dist/query-builders/functions/string.js +518 -0
  273. package/dist/query-builders/functions/window.js +328 -0
  274. package/dist/query-builders/include-builder.js +323 -0
  275. package/dist/query-builders/index-expression-builder.js +242 -0
  276. package/dist/query-builders/index.js +161 -0
  277. package/dist/query-builders/insert-builder.js +164 -0
  278. package/dist/query-builders/model-helpers.js +38 -0
  279. package/dist/query-builders/order-limit-builder.js +239 -0
  280. package/dist/query-builders/sql-compiler.js +2040 -0
  281. package/dist/query-builders/subquery-builder.js +152 -0
  282. package/dist/query-builders/update-builder.js +182 -0
  283. package/dist/query-builders/view-builder.js +218 -0
  284. package/dist/query-builders/where-builder.js +1532 -0
  285. package/dist/query-interface.js +622 -0
  286. package/dist/query-optimizers/batch-optimizer.js +426 -0
  287. package/dist/query-optimizers/explain-plans.js +415 -0
  288. package/dist/query-optimizers/index.js +51 -0
  289. package/dist/query-optimizers/prepared-statement-cache.js +423 -0
  290. package/dist/query-optimizers/query-hints.js +438 -0
  291. package/dist/query-optimizers/query-optimizer.js +278 -0
  292. package/dist/query-optimizers/slow-query-logger.js +271 -0
  293. package/dist/replica-manager.js +507 -0
  294. package/dist/schema/index.js +15 -0
  295. package/dist/schema/migration-generator.js +374 -0
  296. package/dist/schema/schema-differ.js +549 -0
  297. package/dist/schema/types.js +6 -0
  298. package/dist/sql-constants.js +300 -0
  299. package/dist/sqlite-advanced.js +1047 -0
  300. package/dist/streams/index.js +12 -0
  301. package/dist/streams/transforms.js +178 -0
  302. package/dist/transaction.js +456 -0
  303. package/dist/types/index.js +180 -0
  304. package/dist/user-management.js +127 -0
  305. package/dist/utils/date.js +300 -0
  306. package/dist/utils/index.js +1079 -0
  307. package/dist/utils/string.js +161 -0
  308. package/dist/validators/index.js +19 -0
  309. package/dist/validators/validator.js +911 -0
  310. package/package.json +190 -0
@@ -0,0 +1,399 @@
1
+ "use strict";
2
+ /**
3
+ * Typed math-function builder API.
4
+ *
5
+ * Provides typed, autocomplete-friendly builders for common SQL math
6
+ * functions (`ROUND`, `CEIL`/`CEILING`, `FLOOR`, `POWER`, `MOD`, random
7
+ * number generation, `GREATEST`/`LEAST`, `TRUNC`/`TRUNCATE`, ...) across all
8
+ * 11 supported dialects, so callers never need to hand-write raw,
9
+ * dialect-specific SQL for these.
10
+ *
11
+ * This module is intentionally self-contained: it does not add any new
12
+ * dispatch branches to the shared SQL compiler. Every builder resolves
13
+ * directly to a final, dialect-correct SQL fragment string, which is then
14
+ * wrapped with the existing `literal()` helper from `src/operators.ts` so it
15
+ * slots into `attributes: [...]`, `where`, etc. exactly the way `fn()`/
16
+ * `col()`/`cast()` do today.
17
+ *
18
+ * Dialect quirks verified while building this (do not assume symmetry with
19
+ * Postgres/MySQL):
20
+ *
21
+ * - `RANDOM()`/`RAND()` do NOT uniformly return a float in `[0, 1)`:
22
+ * - mysql / mariadb / mssql / db2: `RAND()` -> float in [0, 1).
23
+ * - postgres / cockroachdb / redshift: `RANDOM()` -> float in [0, 1).
24
+ * - sqlite: `RANDOM()` returns a *signed 64-bit integer*
25
+ * (-2^63 .. 2^63-1), NOT a [0,1) float. It must be normalized.
26
+ * - snowflake: `RANDOM()` returns a random *64-bit integer* as well
27
+ * (not [0,1)); the documented way to get a uniform float is
28
+ * `UNIFORM(0::FLOAT, 1::FLOAT, RANDOM())`.
29
+ * - oracle: no `RANDOM()`/`RAND()` at all -- must use
30
+ * `DBMS_RANDOM.VALUE`.
31
+ * - clickhouse: `rand()` returns a `UInt32` (0 .. 2^32-1), NOT [0,1).
32
+ * The [0,1) equivalent is `randCanonical()`.
33
+ *
34
+ * - `CEIL` vs `CEILING`: T-SQL (mssql) has no `CEIL` function at all --
35
+ * only `CEILING`. All other dialects here accept `CEIL`.
36
+ *
37
+ * - `GREATEST`/`LEAST`: not supported natively before SQL Server 2022, so
38
+ * mssql gets a portable nested-`CASE` fallback here (works on every
39
+ * supported SQL Server version, not just 2022+). sqlite has no
40
+ * `GREATEST`/`LEAST` keywords either, but its scalar `MAX`/`MIN` (called
41
+ * with 2+ arguments) behave exactly like `GREATEST`/`LEAST`, so that is
42
+ * used instead.
43
+ *
44
+ * - `MOD`: mssql has no `MOD()` function -- only the `%` operator.
45
+ * clickhouse's function is named `modulo`, not `mod`.
46
+ *
47
+ * - `TRUNCATE`/`TRUNC`: MySQL/MariaDB use `TRUNCATE(value, decimals)`;
48
+ * Oracle/Postgres/CockroachDB/Redshift/DB2/Snowflake use
49
+ * `TRUNC(value, decimals)`; mssql has neither -- truncation is done via
50
+ * `ROUND(value, decimals, 1)` (the undocumented-looking-but-real third
51
+ * "truncate instead of round" argument of T-SQL's `ROUND`); sqlite's
52
+ * `trunc()` math-extension function only takes a single argument (no
53
+ * decimals), so a `TRUNC(value * 10^n) / 10^n` fallback is used when
54
+ * `decimals` is supplied.
55
+ *
56
+ * - ClickHouse function names are matched to ClickHouse's own lower-case
57
+ * documented spelling (`round`, `floor`, `ceil`, `abs`, `sign`, `pow`,
58
+ * `modulo`, `trunc`, `greatest`, `least`, `rand`, `randCanonical`) rather
59
+ * than upper-cased ANSI style, since not all of them have registered
60
+ * case-insensitive aliases.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * import { round, power, random, greatest } from './query-builders/functions/math';
65
+ * import { col } from '../../operators';
66
+ *
67
+ * User.findAll({
68
+ * attributes: [
69
+ * [round('postgres', col('price'), 2), 'roundedPrice'],
70
+ * [power('postgres', col('base'), 2), 'squared'],
71
+ * [random('postgres'), 'rnd'],
72
+ * [greatest('mssql', col('a'), col('b'), 10), 'best'],
73
+ * ],
74
+ * });
75
+ * ```
76
+ */
77
+ Object.defineProperty(exports, "__esModule", { value: true });
78
+ exports.round = round;
79
+ exports.ceil = ceil;
80
+ exports.floor = floor;
81
+ exports.power = power;
82
+ exports.sqrt = sqrt;
83
+ exports.abs = abs;
84
+ exports.sign = sign;
85
+ exports.mod = mod;
86
+ exports.random = random;
87
+ exports.greatest = greatest;
88
+ exports.least = least;
89
+ exports.truncate = truncate;
90
+ const operators_1 = require("../../operators");
91
+ /** Identifier quote style used per dialect when rendering `col()` refs. */
92
+ function quoteIdentifier(dialect, name) {
93
+ const parts = name.split('.');
94
+ const quoteOne = (part) => {
95
+ if (dialect === 'mysql' || dialect === 'mariadb') {
96
+ return `\`${part.replace(/`/g, '``')}\``;
97
+ }
98
+ if (dialect === 'mssql') {
99
+ return `[${part.replace(/]/g, ']]')}]`;
100
+ }
101
+ // postgres, sqlite, cockroachdb, redshift, db2, oracle, snowflake, clickhouse
102
+ return `"${part.replace(/"/g, '""')}"`;
103
+ };
104
+ return parts.map(quoteOne).join('.');
105
+ }
106
+ /** Escape a plain string as a single-quoted SQL string literal. */
107
+ function quoteStringLiteral(value) {
108
+ return `'${value.replace(/'/g, "''")}'`;
109
+ }
110
+ /**
111
+ * Flatten a math-function argument (string, number, ColExpression,
112
+ * FnExpression, LiteralExpression) into a raw SQL fragment string.
113
+ *
114
+ * Per this module's contract: plain strings/numbers are rendered as literal
115
+ * SQL *values* (not identifiers) -- use `col()` to reference a column.
116
+ */
117
+ function toSqlFragment(dialect, arg) {
118
+ if (typeof arg === 'number') {
119
+ return String(arg);
120
+ }
121
+ if (typeof arg === 'string') {
122
+ return quoteStringLiteral(arg);
123
+ }
124
+ if ((0, operators_1.isFnExpression)(arg)) {
125
+ const args = arg.args.map((a) => toSqlFragment(dialect, a)).join(', ');
126
+ return `${arg.fn}(${args})`;
127
+ }
128
+ if ((0, operators_1.isColExpression)(arg)) {
129
+ return quoteIdentifier(dialect, arg.col);
130
+ }
131
+ if ((0, operators_1.isLiteralExpression)(arg)) {
132
+ // Handles both { __type: 'literal', sql } and { $literal: sql } shapes.
133
+ return arg.sql ?? arg.$literal;
134
+ }
135
+ // Fallback: stringify.
136
+ return String(arg);
137
+ }
138
+ function isClickhouse(dialect) {
139
+ return dialect === 'clickhouse';
140
+ }
141
+ function isMssql(dialect) {
142
+ return dialect === 'mssql';
143
+ }
144
+ function isSqlite(dialect) {
145
+ return dialect === 'sqlite';
146
+ }
147
+ /**
148
+ * Build a nested CASE expression that computes GREATEST/LEAST-equivalent
149
+ * semantics for dialects lacking a native function (used for mssql, which
150
+ * has no GREATEST/LEAST before SQL Server 2022).
151
+ *
152
+ * @param comparator '>=' for GREATEST, '<=' for LEAST
153
+ */
154
+ function caseBasedExtreme(dialect, values, comparator) {
155
+ // Build, for each candidate index i, the condition that value[i] is the
156
+ // extreme among all values (i.e. value[i] <comparator> value[j] for all j).
157
+ function build(remaining) {
158
+ if (remaining.length === 1) {
159
+ return remaining[0];
160
+ }
161
+ const [first, ...rest] = remaining;
162
+ const conditions = values.map((v) => `${first} ${comparator} ${v}`).join(' AND ');
163
+ return `CASE WHEN ${conditions} THEN ${first} ELSE ${build(rest)} END`;
164
+ }
165
+ return build(values);
166
+ }
167
+ /**
168
+ * `ROUND(value[, decimals])`
169
+ *
170
+ * ANSI-consistent across all 11 dialects: MySQL, MariaDB, Postgres, MSSQL,
171
+ * Oracle, SQLite (math-functions extension, 3.35+), CockroachDB, Redshift,
172
+ * DB2, Snowflake, and ClickHouse all accept an optional second `decimals`
173
+ * argument with the same semantics.
174
+ */
175
+ function round(dialect, expr, decimals) {
176
+ const value = toSqlFragment(dialect, expr);
177
+ const fnName = isClickhouse(dialect) ? 'round' : 'ROUND';
178
+ const args = decimals !== undefined ? `${value}, ${decimals}` : value;
179
+ return (0, operators_1.literal)(`${fnName}(${args})`);
180
+ }
181
+ /**
182
+ * `CEIL(value)` / `CEILING(value)`.
183
+ *
184
+ * mssql has no `CEIL` -- only `CEILING`. Every other dialect here accepts
185
+ * `CEIL` (ClickHouse spells it lower-case).
186
+ */
187
+ function ceil(dialect, expr) {
188
+ const value = toSqlFragment(dialect, expr);
189
+ let fnName;
190
+ if (isMssql(dialect)) {
191
+ fnName = 'CEILING';
192
+ }
193
+ else if (isClickhouse(dialect)) {
194
+ fnName = 'ceil';
195
+ }
196
+ else {
197
+ fnName = 'CEIL';
198
+ }
199
+ return (0, operators_1.literal)(`${fnName}(${value})`);
200
+ }
201
+ /**
202
+ * `FLOOR(value)`. Consistent naming across all 11 dialects.
203
+ */
204
+ function floor(dialect, expr) {
205
+ const value = toSqlFragment(dialect, expr);
206
+ const fnName = isClickhouse(dialect) ? 'floor' : 'FLOOR';
207
+ return (0, operators_1.literal)(`${fnName}(${value})`);
208
+ }
209
+ /**
210
+ * `POWER(base, exponent)`.
211
+ *
212
+ * Consistent across all 11 dialects (SQLite's math-functions extension
213
+ * registers both `pow` and `power` as synonyms; ClickHouse registers `pow`
214
+ * and `power` as synonyms too -- lower-cased here for ClickHouse).
215
+ */
216
+ function power(dialect, base, exponent) {
217
+ const b = toSqlFragment(dialect, base);
218
+ const e = toSqlFragment(dialect, exponent);
219
+ const fnName = isClickhouse(dialect) ? 'pow' : 'POWER';
220
+ return (0, operators_1.literal)(`${fnName}(${b}, ${e})`);
221
+ }
222
+ /**
223
+ * `SQRT(value)`. Consistent naming across all 11 dialects.
224
+ */
225
+ function sqrt(dialect, expr) {
226
+ const value = toSqlFragment(dialect, expr);
227
+ const fnName = isClickhouse(dialect) ? 'sqrt' : 'SQRT';
228
+ return (0, operators_1.literal)(`${fnName}(${value})`);
229
+ }
230
+ /**
231
+ * `ABS(value)`. Consistent naming across all 11 dialects.
232
+ */
233
+ function abs(dialect, expr) {
234
+ const value = toSqlFragment(dialect, expr);
235
+ const fnName = isClickhouse(dialect) ? 'abs' : 'ABS';
236
+ return (0, operators_1.literal)(`${fnName}(${value})`);
237
+ }
238
+ /**
239
+ * `SIGN(value)` -- returns -1/0/1.
240
+ *
241
+ * Every dialect here has a native `SIGN()` function EXCEPT sqlite, whose
242
+ * built-in math-functions extension does not include `sign` at all -- so a
243
+ * portable `CASE` expression is used for sqlite instead.
244
+ */
245
+ function sign(dialect, expr) {
246
+ const value = toSqlFragment(dialect, expr);
247
+ if (isSqlite(dialect)) {
248
+ return (0, operators_1.literal)(`(CASE WHEN ${value} > 0 THEN 1 WHEN ${value} < 0 THEN -1 ELSE 0 END)`);
249
+ }
250
+ const fnName = isClickhouse(dialect) ? 'sign' : 'SIGN';
251
+ return (0, operators_1.literal)(`${fnName}(${value})`);
252
+ }
253
+ /**
254
+ * `MOD(dividend, divisor)`.
255
+ *
256
+ * mssql has no `MOD()` function at all -- only the `%` operator, so mssql
257
+ * renders `(dividend % divisor)`. ClickHouse's function is named `modulo`
258
+ * (not `mod`). Every other dialect here has a native `MOD(a, b)` function.
259
+ */
260
+ function mod(dialect, dividend, divisor) {
261
+ const a = toSqlFragment(dialect, dividend);
262
+ const b = toSqlFragment(dialect, divisor);
263
+ if (isMssql(dialect)) {
264
+ return (0, operators_1.literal)(`(${a} % ${b})`);
265
+ }
266
+ if (isClickhouse(dialect)) {
267
+ return (0, operators_1.literal)(`modulo(${a}, ${b})`);
268
+ }
269
+ return (0, operators_1.literal)(`MOD(${a}, ${b})`);
270
+ }
271
+ /**
272
+ * Random value in `[0, 1)`, using the REAL per-dialect function/expression
273
+ * (deliberately not assumed symmetric):
274
+ *
275
+ * - mysql / mariadb: `RAND()`
276
+ * - postgres / cockroachdb / redshift: `RANDOM()`
277
+ * - mssql: `RAND()`
278
+ * - oracle: `DBMS_RANDOM.VALUE` (no `RAND()`/`RANDOM()` exists in Oracle)
279
+ * - db2: `RAND()`
280
+ * - sqlite: `RANDOM()` returns a signed 64-bit *integer*, not a [0,1)
281
+ * float -- normalized here via `(0.5 + RANDOM() / 18446744073709551616.0)`.
282
+ * - snowflake: `RANDOM()` also returns a 64-bit integer, not [0,1) --
283
+ * normalized here via `UNIFORM(0::FLOAT, 1::FLOAT, RANDOM())`, which is
284
+ * Snowflake's documented way to get a uniform float.
285
+ * - clickhouse: `rand()` returns a `UInt32`, not [0,1) -- `randCanonical()`
286
+ * is ClickHouse's documented [0,1) float generator.
287
+ */
288
+ function random(dialect) {
289
+ switch (dialect) {
290
+ case 'mysql':
291
+ case 'mariadb':
292
+ case 'mssql':
293
+ case 'db2':
294
+ return (0, operators_1.literal)('RAND()');
295
+ case 'postgres':
296
+ case 'cockroachdb':
297
+ case 'redshift':
298
+ return (0, operators_1.literal)('RANDOM()');
299
+ case 'oracle':
300
+ return (0, operators_1.literal)('DBMS_RANDOM.VALUE');
301
+ case 'sqlite':
302
+ return (0, operators_1.literal)('(0.5 + CAST(RANDOM() AS REAL) / 18446744073709551616.0)');
303
+ case 'snowflake':
304
+ return (0, operators_1.literal)('UNIFORM(0::FLOAT, 1::FLOAT, RANDOM())');
305
+ case 'clickhouse':
306
+ return (0, operators_1.literal)('randCanonical()');
307
+ default:
308
+ return (0, operators_1.literal)('RANDOM()');
309
+ }
310
+ }
311
+ /**
312
+ * `GREATEST(v1, v2, ...)`.
313
+ *
314
+ * - mssql: no native `GREATEST` before SQL Server 2022 -- a portable nested
315
+ * `CASE` expression is used so it works on every supported SQL Server
316
+ * version (not just 2022+).
317
+ * - sqlite: no `GREATEST` keyword -- but scalar `MAX(v1, v2, ...)` (called
318
+ * with 2+ args) behaves exactly like `GREATEST`, so that is used instead.
319
+ * - every other dialect here has native `GREATEST(...)`.
320
+ */
321
+ function greatest(dialect, ...values) {
322
+ if (values.length === 0) {
323
+ throw new Error('greatest() requires at least one value');
324
+ }
325
+ const rendered = values.map((v) => toSqlFragment(dialect, v));
326
+ if (rendered.length === 1) {
327
+ return (0, operators_1.literal)(rendered[0]);
328
+ }
329
+ if (isMssql(dialect)) {
330
+ return (0, operators_1.literal)(caseBasedExtreme(dialect, rendered, '>='));
331
+ }
332
+ if (isSqlite(dialect)) {
333
+ return (0, operators_1.literal)(`MAX(${rendered.join(', ')})`);
334
+ }
335
+ const fnName = isClickhouse(dialect) ? 'greatest' : 'GREATEST';
336
+ return (0, operators_1.literal)(`${fnName}(${rendered.join(', ')})`);
337
+ }
338
+ /**
339
+ * `LEAST(v1, v2, ...)`.
340
+ *
341
+ * Same quirks as {@link greatest}: mssql falls back to a nested `CASE`
342
+ * expression, sqlite uses scalar `MIN(v1, v2, ...)`.
343
+ */
344
+ function least(dialect, ...values) {
345
+ if (values.length === 0) {
346
+ throw new Error('least() requires at least one value');
347
+ }
348
+ const rendered = values.map((v) => toSqlFragment(dialect, v));
349
+ if (rendered.length === 1) {
350
+ return (0, operators_1.literal)(rendered[0]);
351
+ }
352
+ if (isMssql(dialect)) {
353
+ return (0, operators_1.literal)(caseBasedExtreme(dialect, rendered, '<='));
354
+ }
355
+ if (isSqlite(dialect)) {
356
+ return (0, operators_1.literal)(`MIN(${rendered.join(', ')})`);
357
+ }
358
+ const fnName = isClickhouse(dialect) ? 'least' : 'LEAST';
359
+ return (0, operators_1.literal)(`${fnName}(${rendered.join(', ')})`);
360
+ }
361
+ /**
362
+ * Truncate a value toward zero (no rounding), optionally to `decimals`
363
+ * decimal places.
364
+ *
365
+ * - mysql / mariadb: `TRUNCATE(value, decimals)` (function name is
366
+ * `TRUNCATE`, not `TRUNC`; decimals defaults to 0 when omitted).
367
+ * - oracle / postgres / cockroachdb / redshift / db2 / snowflake:
368
+ * `TRUNC(value, decimals)`.
369
+ * - mssql: no `TRUNC`/`TRUNCATE` function at all -- uses the (real, if
370
+ * obscure) third argument of T-SQL's `ROUND(value, decimals, function)`,
371
+ * where a non-zero third argument truncates instead of rounding:
372
+ * `ROUND(value, decimals, 1)`.
373
+ * - sqlite: the math-functions extension's `trunc(X)` only accepts a single
374
+ * argument (no decimals support) -- when `decimals` is supplied, a
375
+ * `TRUNC(value * 10^n) / 10^n` fallback is used.
376
+ * - clickhouse: `trunc(value, decimals)` (lower-case, 2-arg form supported).
377
+ */
378
+ function truncate(dialect, expr, decimals) {
379
+ const value = toSqlFragment(dialect, expr);
380
+ const d = decimals ?? 0;
381
+ if (dialect === 'mysql' || dialect === 'mariadb') {
382
+ return (0, operators_1.literal)(`TRUNCATE(${value}, ${d})`);
383
+ }
384
+ if (isMssql(dialect)) {
385
+ return (0, operators_1.literal)(`ROUND(${value}, ${d}, 1)`);
386
+ }
387
+ if (isSqlite(dialect)) {
388
+ if (decimals === undefined || decimals === 0) {
389
+ return (0, operators_1.literal)(`trunc(${value})`);
390
+ }
391
+ const factor = Math.pow(10, decimals);
392
+ return (0, operators_1.literal)(`(trunc((${value}) * ${factor}) / ${factor}.0)`);
393
+ }
394
+ if (isClickhouse(dialect)) {
395
+ return (0, operators_1.literal)(decimals !== undefined ? `trunc(${value}, ${decimals})` : `trunc(${value})`);
396
+ }
397
+ // oracle, postgres, cockroachdb, redshift, db2, snowflake
398
+ return (0, operators_1.literal)(`TRUNC(${value}, ${d})`);
399
+ }