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,457 @@
1
+ "use strict";
2
+ /**
3
+ * Greenplum dialect implementation for the TypeScript ORM.
4
+ *
5
+ * Greenplum Database is a massively-parallel-processing (MPP) analytics
6
+ * database built by forking PostgreSQL (historically the 8.2/8.3 line, with
7
+ * later releases rebased onto PostgreSQL 9.x and 12). Because it speaks the
8
+ * PostgreSQL wire protocol and is largely SQL-compatible with it, this dialect
9
+ * extends {@link PostgresDialect} and reuses the same `pg` driver (default port
10
+ * 5432, exactly like Postgres — the coordinator/master segment listens on the
11
+ * standard Postgres port).
12
+ *
13
+ * Notable Greenplum-specific differences vs. plain PostgreSQL that this dialect
14
+ * models on top of the inherited Postgres behavior:
15
+ *
16
+ * - Distribution policy: every Greenplum table is physically distributed across
17
+ * segments. `CREATE TABLE` accepts a trailing `DISTRIBUTED BY (cols)` /
18
+ * `DISTRIBUTED RANDOMLY` / `DISTRIBUTED REPLICATED` clause. This dialect emits
19
+ * that clause when a distribution option is supplied (see
20
+ * {@link GreenplumDialect.buildDistributionClause}). To stay safe against
21
+ * plain-Postgres targets it only emits the clause when explicitly asked; when
22
+ * asked but under-specified it defaults to `DISTRIBUTED RANDOMLY`.
23
+ * - Append-optimized / column-oriented storage: Greenplum supports
24
+ * append-optimized (AO) tables and column orientation with compression via a
25
+ * table `WITH (appendoptimized=true, orientation=column, compresstype=zstd)`
26
+ * storage clause (see {@link GreenplumDialect.buildStorageClause}).
27
+ * - Legacy partitioning: in addition to Postgres 10+ declarative partitioning
28
+ * (inherited from the base dialect), Greenplum has its own older
29
+ * `PARTITION BY RANGE(col) (START (...) END (...) EVERY (...))` syntax
30
+ * (see {@link GreenplumDialect.buildRangePartitionClause}).
31
+ * - External tables: `CREATE EXTERNAL TABLE ... LOCATION ('gpfdist://...')
32
+ * FORMAT '...'` exposes external data (e.g. served by the `gpfdist` file
33
+ * distribution daemon) as a readable/writable table
34
+ * (see {@link GreenplumDialect.buildExternalTableSQL}).
35
+ *
36
+ * Greenplum does NOT support some PostgreSQL features (e.g. `SERIAL` maps to a
37
+ * distributed sequence, no global secondary UNIQUE guarantees unless the
38
+ * distribution key is a subset of the constraint, no savepoints inside some
39
+ * plans). Those caveats are inherited-as-is from the Postgres behavior here and
40
+ * are out of scope for this dialect wrapper.
41
+ */
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.GreenplumDialect = void 0;
44
+ exports.createGreenplumDialect = createGreenplumDialect;
45
+ const index_1 = require("../postgres/index");
46
+ /**
47
+ * Greenplum dialect class. Extends {@link PostgresDialect}, overriding the
48
+ * `CREATE TABLE` builder to append Greenplum distribution/storage clauses and
49
+ * adding helpers for legacy range partitioning and external tables.
50
+ */
51
+ class GreenplumDialect extends index_1.PostgresDialect {
52
+ constructor(config) {
53
+ // Greenplum's coordinator listens on the standard Postgres port 5432.
54
+ super({ port: 5432, ...config });
55
+ // Explicit `string` type (rather than the inferred `'greenplum'` literal)
56
+ // keeps this assignable to the base `readonly name: string` property.
57
+ this.name = 'greenplum';
58
+ this.library = 'pg';
59
+ }
60
+ // ==========================================================================
61
+ // Distribution policy
62
+ // ==========================================================================
63
+ /**
64
+ * Build the trailing `DISTRIBUTED ...` clause for a Greenplum `CREATE TABLE`.
65
+ *
66
+ * Returns an empty string when no distribution option is supplied, so callers
67
+ * that never set one produce plain-Postgres-compatible DDL. When a
68
+ * distribution intent is expressed but under-specified (e.g. an empty
69
+ * `distributedBy` array), it falls back to `DISTRIBUTED RANDOMLY`.
70
+ *
71
+ * @returns e.g. `DISTRIBUTED BY ("id")`, `DISTRIBUTED RANDOMLY`,
72
+ * `DISTRIBUTED REPLICATED`, or `''`.
73
+ */
74
+ buildDistributionClause(options) {
75
+ if (!options) {
76
+ return '';
77
+ }
78
+ if (options.distributedReplicated) {
79
+ return 'DISTRIBUTED REPLICATED';
80
+ }
81
+ if (options.distributedBy && options.distributedBy.length > 0) {
82
+ const cols = options.distributedBy.map((c) => this.escapeId(c)).join(', ');
83
+ return `DISTRIBUTED BY (${cols})`;
84
+ }
85
+ // Either `distributedRandomly` was set, or a distribution intent was
86
+ // expressed without usable columns — default to random distribution.
87
+ if (options.distributedRandomly ||
88
+ options.distributedBy !== undefined ||
89
+ options.distributedReplicated !== undefined) {
90
+ return 'DISTRIBUTED RANDOMLY';
91
+ }
92
+ return '';
93
+ }
94
+ // ==========================================================================
95
+ // Append-optimized / columnar storage
96
+ // ==========================================================================
97
+ /**
98
+ * Build the `WITH (...)` storage clause for append-optimized / column-
99
+ * oriented Greenplum tables. Returns `''` unless append-optimized storage is
100
+ * requested (via `appendOptimized`, a non-`row` `orientation`, or any of the
101
+ * compression parameters).
102
+ *
103
+ * @returns e.g. `WITH (appendoptimized=true, orientation=column, compresstype=zstd)`.
104
+ */
105
+ buildStorageClause(options) {
106
+ if (!options) {
107
+ return '';
108
+ }
109
+ const wantsAO = options.appendOptimized === true ||
110
+ options.orientation !== undefined ||
111
+ options.compressType !== undefined ||
112
+ options.compressLevel !== undefined ||
113
+ options.blocksize !== undefined;
114
+ if (!wantsAO) {
115
+ return '';
116
+ }
117
+ const params = ['appendoptimized=true'];
118
+ if (options.orientation) {
119
+ params.push(`orientation=${options.orientation}`);
120
+ }
121
+ if (options.compressType) {
122
+ params.push(`compresstype=${options.compressType}`);
123
+ }
124
+ if (options.compressLevel !== undefined) {
125
+ params.push(`compresslevel=${options.compressLevel}`);
126
+ }
127
+ if (options.blocksize !== undefined) {
128
+ params.push(`blocksize=${options.blocksize}`);
129
+ }
130
+ return `WITH (${params.join(', ')})`;
131
+ }
132
+ // ==========================================================================
133
+ // CREATE TABLE
134
+ // ==========================================================================
135
+ /**
136
+ * Synchronously build the full Greenplum `CREATE TABLE` statement, including
137
+ * the append-optimized storage `WITH (...)` clause and the trailing
138
+ * `DISTRIBUTED ...` clause. Exposed as a sync builder so callers (and tests)
139
+ * can inspect the emitted SQL without a live connection.
140
+ */
141
+ buildCreateTableSQL(tableName, columns, options) {
142
+ const defs = Object.entries(columns).map(([name, def]) => this.buildGreenplumColumnSql(name, def));
143
+ // Table-level constraints are emitted inside the column list.
144
+ for (const c of options?.constraints ?? []) {
145
+ defs.push(this.buildTableConstraintSql(c));
146
+ }
147
+ let sql = 'CREATE TABLE';
148
+ if (options?.ifNotExists) {
149
+ sql += ' IF NOT EXISTS';
150
+ }
151
+ sql += ` ${this.escapeId(tableName)} (${defs.join(', ')})`;
152
+ // Legacy inheritance / declarative partitioning passthrough.
153
+ if (options?.inherit) {
154
+ sql += ` INHERITS (${this.escapeId(options.inherit)})`;
155
+ }
156
+ if (options?.partitionBy) {
157
+ sql += ` PARTITION BY ${options.partitionBy}`;
158
+ }
159
+ // Append-optimized / columnar storage parameters.
160
+ const storage = this.buildStorageClause(options);
161
+ if (storage) {
162
+ sql += ` ${storage}`;
163
+ }
164
+ // TABLESPACE follows storage/partitioning and precedes the DISTRIBUTED clause.
165
+ if (options?.tablespace) {
166
+ sql += ` TABLESPACE ${options.tablespace}`;
167
+ }
168
+ // Distribution policy — must be the final clause on a Greenplum CREATE TABLE.
169
+ const distribution = this.buildDistributionClause(options);
170
+ if (distribution) {
171
+ sql += ` ${distribution}`;
172
+ }
173
+ return sql;
174
+ }
175
+ /**
176
+ * Build a single table-level constraint clause for the CREATE TABLE column
177
+ * list, e.g. `CONSTRAINT "pk_orders" PRIMARY KEY ("id")` or
178
+ * `FOREIGN KEY ("customer_id") REFERENCES "customers"("id")`.
179
+ */
180
+ buildTableConstraintSql(c) {
181
+ const prefix = c.name ? `CONSTRAINT ${this.escapeId(c.name)} ` : '';
182
+ const cols = (c.fields ?? []).map((f) => this.escapeId(f)).join(', ');
183
+ switch (c.type) {
184
+ case 'PRIMARY KEY':
185
+ return `${prefix}PRIMARY KEY (${cols})`;
186
+ case 'UNIQUE':
187
+ return `${prefix}UNIQUE (${cols})`;
188
+ case 'FOREIGN KEY': {
189
+ const ref = c.references;
190
+ const refClause = ref
191
+ ? ` REFERENCES ${this.escapeId(ref.table)}(${this.escapeId(ref.field)})`
192
+ : '';
193
+ return `${prefix}FOREIGN KEY (${cols})${refClause}`;
194
+ }
195
+ case 'CHECK':
196
+ return `${prefix}CHECK (${c.expression ?? ''})`;
197
+ }
198
+ }
199
+ // ==========================================================================
200
+ // Upsert — Greenplum has no INSERT ... ON CONFLICT
201
+ // ==========================================================================
202
+ /**
203
+ * Greenplum (Postgres 8/9-derived) does not implement `INSERT ... ON
204
+ * CONFLICT`. Refuse an upsert INSERT with a clear error pointing callers at
205
+ * {@link GreenplumDialect.buildUpsertQuery}'s staging-table strategy. Plain
206
+ * (non-upsert) inserts delegate to the inherited PostgreSQL builder.
207
+ */
208
+ buildInsertQuery(tableName, values, options) {
209
+ if (options?.upsert) {
210
+ throw new Error('GreenplumDialect: INSERT ... ON CONFLICT upsert is not supported by Greenplum ' +
211
+ '(Postgres 8/9-derived). Use buildUpsertQuery(), which emits a staging-table ' +
212
+ 'CREATE TEMP + DELETE ... USING + INSERT ... SELECT strategy instead.');
213
+ }
214
+ return super.buildInsertQuery(tableName, values, options);
215
+ }
216
+ /**
217
+ * Build a Greenplum-compatible upsert as a staging-table batch (no
218
+ * `ON CONFLICT`):
219
+ *
220
+ * CREATE TEMP TABLE "<t>_gp_upsert_stg" (LIKE "<t>") ON COMMIT DROP;
221
+ * INSERT INTO "<t>_gp_upsert_stg" (cols) VALUES (...);
222
+ * DELETE FROM "<t>" USING stg WHERE "<t>".k = stg.k [AND ...];
223
+ * INSERT INTO "<t>" (writeCols) SELECT writeCols FROM stg [RETURNING ...];
224
+ * [DROP TABLE stg] -- only when no RETURNING (RETURNING must be the last statement)
225
+ *
226
+ * `writeCols` is the conflict keys plus `updateOnDuplicate` when given,
227
+ * otherwise every provided column.
228
+ */
229
+ buildUpsertQuery(tableName, values, options) {
230
+ const conflictFields = options?.conflictFields ?? [];
231
+ if (conflictFields.length === 0) {
232
+ throw new Error('GreenplumDialect.buildUpsertQuery: options.conflictFields is required — the ' +
233
+ 'staging-table strategy matches existing rows on these key columns.');
234
+ }
235
+ const cols = Object.keys(values);
236
+ const qTable = this.escapeId(tableName);
237
+ const stg = this.escapeId(`${tableName}_gp_upsert_stg`);
238
+ const q = (c) => this.escapeId(c);
239
+ // Columns written back into the target: keys + updated columns, else all.
240
+ const writeCols = options?.updateOnDuplicate && options.updateOnDuplicate.length > 0
241
+ ? Array.from(new Set([...conflictFields, ...options.updateOnDuplicate]))
242
+ : cols;
243
+ const placeholders = cols.map((_, i) => `$${i + 1}`).join(', ');
244
+ const joinCond = conflictFields
245
+ .map((k) => `${qTable}.${q(k)} = ${stg}.${q(k)}`)
246
+ .join(' AND ');
247
+ const writeList = writeCols.map(q).join(', ');
248
+ const statements = [
249
+ `CREATE TEMP TABLE ${stg} (LIKE ${qTable}) ON COMMIT DROP`,
250
+ `INSERT INTO ${stg} (${cols.map(q).join(', ')}) VALUES (${placeholders})`,
251
+ `DELETE FROM ${qTable} USING ${stg} WHERE ${joinCond}`,
252
+ ];
253
+ let finalInsert = `INSERT INTO ${qTable} (${writeList}) SELECT ${writeList} FROM ${stg}`;
254
+ if (options?.returning === true) {
255
+ finalInsert += ' RETURNING *';
256
+ }
257
+ else if (Array.isArray(options?.returning) && options.returning.length > 0) {
258
+ finalInsert += ` RETURNING ${options.returning.map(q).join(', ')}`;
259
+ }
260
+ statements.push(finalInsert);
261
+ // RETURNING must be the last statement; otherwise eagerly drop the staging
262
+ // table (it is also ON COMMIT DROP as a safety net).
263
+ if (!options?.returning) {
264
+ statements.push(`DROP TABLE ${stg}`);
265
+ }
266
+ return { sql: statements.join(';\n'), values: Object.values(values) };
267
+ }
268
+ /**
269
+ * Create a new table, emitting Greenplum distribution and append-optimized
270
+ * storage clauses. Overrides {@link PostgresDialect.createTable}.
271
+ */
272
+ async createTable(tableName, columns, options) {
273
+ const sql = this.buildCreateTableSQL(tableName, columns, options);
274
+ await this.query(sql);
275
+ // Table comment (inherited COMMENT ON semantics).
276
+ if (options?.comment) {
277
+ await this.query(`COMMENT ON TABLE ${this.escapeId(tableName)} IS ${this.escape(options.comment)}`);
278
+ }
279
+ // Post-creation indexes, delegated to the inherited addIndex().
280
+ if (options?.indexes) {
281
+ for (const index of options.indexes) {
282
+ await this.addIndex(tableName, index.name || `idx_${tableName}_${index.fields.join('_')}`, index.fields, {
283
+ unique: index.unique,
284
+ type: index.type,
285
+ using: index.using,
286
+ where: index.where,
287
+ expression: index.expression,
288
+ include: index.include,
289
+ });
290
+ }
291
+ }
292
+ }
293
+ /**
294
+ * Build a single column definition for a Greenplum `CREATE TABLE`. Mirrors
295
+ * the common subset of the Postgres column builder (which is private on the
296
+ * base class): type, NOT NULL, DEFAULT, PRIMARY KEY, UNIQUE, and references.
297
+ */
298
+ buildGreenplumColumnSql(columnName, definition) {
299
+ const dt = definition.type;
300
+ // Auto-increment integer columns -> SERIAL (Postgres-compatibility
301
+ // shorthand; Greenplum backs it with a distributed sequence).
302
+ if (definition.autoIncrement && (dt.key === 'INTEGER' || !dt.key)) {
303
+ let sql = `${this.escapeId(columnName)} SERIAL`;
304
+ if (definition.primaryKey)
305
+ sql += ' PRIMARY KEY';
306
+ if (definition.allowNull === false)
307
+ sql += ' NOT NULL';
308
+ if (definition.unique)
309
+ sql += ' UNIQUE';
310
+ return sql;
311
+ }
312
+ let sql = `${this.escapeId(columnName)} ${this.getDataTypeSql(definition.type)}`;
313
+ if (definition.allowNull === false) {
314
+ sql += ' NOT NULL';
315
+ }
316
+ if (definition.defaultValue !== undefined) {
317
+ sql += ` DEFAULT ${this.escape(definition.defaultValue)}`;
318
+ }
319
+ if (definition.primaryKey) {
320
+ sql += ' PRIMARY KEY';
321
+ }
322
+ if (definition.unique) {
323
+ sql += ' UNIQUE';
324
+ }
325
+ if (definition.references) {
326
+ const refField = definition.references.field;
327
+ const refFieldSql = Array.isArray(refField)
328
+ ? `(${refField.map((f) => this.escapeId(f)).join(', ')})`
329
+ : `(${this.escapeId(refField)})`;
330
+ sql += ` REFERENCES ${this.escapeId(definition.references.table)}${refFieldSql}`;
331
+ if (definition.references.onDelete) {
332
+ sql += ` ON DELETE ${definition.references.onDelete}`;
333
+ }
334
+ if (definition.references.onUpdate) {
335
+ sql += ` ON UPDATE ${definition.references.onUpdate}`;
336
+ }
337
+ }
338
+ return sql;
339
+ }
340
+ // ==========================================================================
341
+ // Legacy Greenplum range partitioning
342
+ // ==========================================================================
343
+ /**
344
+ * Build Greenplum's legacy `PARTITION BY RANGE(col) (START (...) END (...)
345
+ * EVERY (...))` clause (distinct from Postgres 10+ declarative partitioning,
346
+ * which the base dialect handles via `PARTITION BY RANGE (col)`).
347
+ *
348
+ * @param column - The range-partition key column.
349
+ * @param spec - Start/end bounds and optional `EVERY` step.
350
+ * @returns e.g.
351
+ * `PARTITION BY RANGE(sale_date) (START ('2020-01-01') END ('2021-01-01') EVERY (INTERVAL '1 month'))`.
352
+ */
353
+ buildRangePartitionClause(column, spec) {
354
+ const parts = [
355
+ `START (${this.formatPartitionBound(spec.start)})`,
356
+ `END (${this.formatPartitionBound(spec.end)})`,
357
+ ];
358
+ if (spec.every !== undefined) {
359
+ parts.push(`EVERY (${this.formatPartitionBound(spec.every)})`);
360
+ }
361
+ return `PARTITION BY RANGE(${this.escapeId(column)}) (${parts.join(' ')})`;
362
+ }
363
+ /**
364
+ * Format a range-partition bound value as a SQL literal: numbers verbatim,
365
+ * already-expression strings (INTERVAL / DATE / TIMESTAMP keyword or a
366
+ * `func(...)` call) raw, and any other string single-quoted.
367
+ */
368
+ formatPartitionBound(value) {
369
+ if (typeof value === 'number') {
370
+ return String(value);
371
+ }
372
+ const trimmed = value.trim();
373
+ if (/^(INTERVAL|DATE|TIMESTAMP|TIME|NUMERIC|MAXVALUE|MINVALUE)\b/i.test(trimmed) ||
374
+ /^[a-zA-Z_][a-zA-Z0-9_.]*\([^)]*\)$/.test(trimmed) ||
375
+ /^'.*'$/.test(trimmed)) {
376
+ return trimmed;
377
+ }
378
+ return `'${trimmed.replace(/'/g, "''")}'`;
379
+ }
380
+ // ==========================================================================
381
+ // External tables (gpfdist / EXTERNAL WEB)
382
+ // ==========================================================================
383
+ /**
384
+ * Build a Greenplum `CREATE EXTERNAL TABLE` statement. External tables expose
385
+ * data served over `gpfdist://`, `http://`, `s3://`, etc. as a queryable
386
+ * (and optionally writable) table with no local segment storage.
387
+ *
388
+ * @param tableName - Name of the external table to create.
389
+ * @param columns - Column definitions (types only; no distribution/constraints).
390
+ * @param options - External-table options (locations, format, writable, ...).
391
+ * @returns e.g.
392
+ * `CREATE EXTERNAL TABLE "ext_sales" (...) LOCATION ('gpfdist://host:8081/sales/*.csv') FORMAT 'CSV' (DELIMITER ',' HEADER)`.
393
+ */
394
+ buildExternalTableSQL(tableName, columns, options) {
395
+ if (!options.locations || options.locations.length === 0) {
396
+ throw new Error('Greenplum external table requires at least one LOCATION.');
397
+ }
398
+ const columnDefs = Object.entries(columns)
399
+ .map(([name, def]) => `${this.escapeId(name)} ${this.getDataTypeSql(def.type)}`)
400
+ .join(', ');
401
+ let sql = 'CREATE';
402
+ if (options.writable) {
403
+ sql += ' WRITABLE';
404
+ }
405
+ sql += ' EXTERNAL';
406
+ if (options.web) {
407
+ sql += ' WEB';
408
+ }
409
+ sql += ' TABLE';
410
+ if (options.ifNotExists) {
411
+ sql += ' IF NOT EXISTS';
412
+ }
413
+ sql += ` ${this.escapeId(tableName)} (${columnDefs})`;
414
+ const locations = options.locations
415
+ .map((loc) => `'${loc.replace(/'/g, "''")}'`)
416
+ .join(', ');
417
+ sql += ` LOCATION (${locations})`;
418
+ const format = options.format || 'TEXT';
419
+ sql += ` FORMAT '${format}'`;
420
+ const formatOpts = [];
421
+ if (options.delimiter !== undefined) {
422
+ formatOpts.push(`DELIMITER '${options.delimiter.replace(/'/g, "''")}'`);
423
+ }
424
+ if (options.header) {
425
+ formatOpts.push('HEADER');
426
+ }
427
+ if (formatOpts.length > 0) {
428
+ sql += ` (${formatOpts.join(' ')})`;
429
+ }
430
+ if (options.encoding) {
431
+ sql += ` ENCODING '${options.encoding.replace(/'/g, "''")}'`;
432
+ }
433
+ if (options.logErrors) {
434
+ sql += ' LOG ERRORS';
435
+ }
436
+ if (options.rejectLimit !== undefined) {
437
+ const unit = options.rejectLimitType || 'ROWS';
438
+ sql += ` SEGMENT REJECT LIMIT ${options.rejectLimit} ${unit}`;
439
+ }
440
+ return sql;
441
+ }
442
+ /**
443
+ * Create an external table by executing the statement built by
444
+ * {@link GreenplumDialect.buildExternalTableSQL}.
445
+ */
446
+ async createExternalTable(tableName, columns, options) {
447
+ await this.query(this.buildExternalTableSQL(tableName, columns, options));
448
+ }
449
+ }
450
+ exports.GreenplumDialect = GreenplumDialect;
451
+ /**
452
+ * Create a new Greenplum dialect instance.
453
+ */
454
+ function createGreenplumDialect(options) {
455
+ return new GreenplumDialect(options || {});
456
+ }
457
+ exports.default = GreenplumDialect;