Skip to content

[Decision] 会说 Postgres 方言的另外两种数据库(Redshift、CockroachDB),平台要不要当 Postgres 来建表?(#11550 的宽半边) #11756

Description

@huangyiirene

由 domain:engine 执行席落卡(session session_01VK8rFDtg8eREaxBGX99Csn)。这是 #11550 被切下来的宽半边。 窄半边(认 knex 自己的规范拼写 postgres / sqlite)已派发 —— 那半边是「我们本来就支持这个方言,只是漏认了一种写法」,不需要谁裁。这半边不一样:它决定平台对外声称支持哪些数据库,属于扩大公开面,恒交维护者。

一句话问题

有两种数据库(Redshift、CockroachDB)会说 Postgres 的话 —— 连上去、发查询、读结果都通。问题是:客户拿它们当数据库时,平台要不要照 Postgres 的方式替他们建表。它们在「怎么存、怎么建表」上和真 Postgres 是有差别的,Redshift 尤其明显。

前提(带 re-check 命令)

三条路,和客户能感觉到的代价

做什么 客户感觉到的代价
A 认:这两种也按 Postgres 发建表语句 客户配上就能跑。⚠️ 但 Redshift 的建表语法确实不同 —— 发错了要么当场建表失败,要么建出一张形状不对的表,而问题要到写数据时才露出来。我们等于永久承诺跟住它们的差异。
B 不认:只认真正的 Postgres 家族拼写 用这两种的客户拿不到任何方言行为(和今天一样)。⚠️ 但失败是静默的 —— 和 #11550 窄半边修的那个缺陷一模一样:不报错,只是把表建错。
C 认「连得上」,不认「照它建表」,并把这条边界写成明文 连接/解析继续按 Postgres 处理(今天就是这样,#11389 是故意的),建表发射不认。客户如果配了这两种,当场拿到一句说清楚的拒绝,而不是一张悄悄建错的表。

业务含义直译:A =「我们说支持 Redshift」;B =「我们没说,你自己看着办」;C =「我们说清楚:连得上,但建表这块我们不替你负责」。

os-decision-facets

  • 实际业务拉动:⚠️ 我不知道有没有客户在用这两种数据库 —— 这是本卡最大的空白(见置信缺口)。如果一个都没有,A 就是在为零需求背一份永久义务;如果有真实客户,那 B 的静默失败就是在坑他们。这一轴我给不出答案,只能交给你。
  • 项目长远合理性:A 让平台永久承担「跟住两个非 Postgres 数据库的 DDL 差异」的义务,而我们连它们差多少都还没量过。C 把边界画在我们实际验证过的地方(连接层验过、发射层没验过),这是一条能诚实守住的线。⇒ 偏 C。
  • 防 AI 写代码犯错:这一轴看出错时谁看到什么。A 出错 = 表建错了、几天后写数据才炸;B 出错 = 完全静默,正是窄半边正在修的那种缺陷;C 出错 = 当场一句响亮的拒绝,作者立刻知道该换数据库还是换配置。⇒ 强推 C,反对 B 的静默。
  • 创业阶段不扩散需求:多声明一个受支持数据库 = 多一份永久测试面和永久维护义务。C 的成本接近于零(把已有的分裂写成明文),A 是三条里最大的一件。⇒ 反对 A。

推荐:C(认 wire、不认 emission,并把边界写明并给出响亮拒绝),回退 B。 四轴里没有一条支持 A,但其中一轴(实际业务拉动)我是空的 —— 如果你知道有客户在用 Redshift,这个推荐要重算。

⚠️ 本分析看不见什么(强制置信缺口):① 有没有客户在用 Redshift / CockroachDB,我完全不知道 —— 这是决定 A 是否值得的那个数字,而我没有;② 我没有实测 Redshift 的 DDL 到底和 Postgres 差多少,所以「A 风险大」是从它的公开文档推的,不是量出来的;③ CockroachDB 和 Redshift 很可能不该同命运(CockroachDB 的 Postgres 兼容性明显更高),把它们绑成一个选项可能本身就是错的 —— 如果你倾向拆开分别裁,说一声。

裁后我会怎么执行(你不用管)

低摩擦裁决格式:回一个字母即可;「C,但 X」我按 C 落地并把 X 记进卡里;不回就留在箱里,⛔ 不会有人替你裁。

相关

Activity

  1. huangyiirene commented on Aug 24, 2026

    @huangyiirene
    CollaboratorAuthor

    Measured while landing the narrow half (#11550 → PR #11783). Two more clients fall inside this decision's scope, so recording them here rather than filing a near-duplicate card.

    The full picture, read from the pinned knex (3.3.0) lib/constants.js plus a live client construction per spelling:

    knex client knex dialect knex driverName recognised for emission today
    postgres / pg / postgresql postgresql pg yes (after PR #11783)
    cockroachdb postgresql cockroachdb no
    redshift redshift pg-redshift no
    pgnative postgresql pgnative no
    mysql / mysql2 mysql mysql / mysql2 yes
    mariadb mariadb mariadb no

    Two things this table adds to the question as framed:

    1. pgnative is the easy end of this decision and is currently lumped in with the hard end. knex resolves it to dialect === 'postgresql' — it is the Postgres dialect, compiled by the same code, differing only in which npm binding carries the bytes. If Redshift is the "diverges on DDL, needs a real ruling" case, pgnative is close to its opposite. Worth answering separately rather than inheriting Redshift's answer by silence. It is also absent from POSTGRES_WIRE_CLIENTS, so today it gets neither emission nor the driver-sql: every Field.date read from PostgreSQL is one day early when the process TZ is east of UTC — toDateOnly() reads UTC components off a local-midnight Date #11389 calendar-day parser pin.

    2. cockroachdb already resolves to knex's postgresql dialect too — so for cockroachdb the question is not "does knex think this is Postgres" (it does) but "does this platform want to claim its DDL is correct there". Redshift is the only one of the four where knex itself says a different dialect.

    mariadb is the same shape one family over: a separate knex dialect, not an alias of mysql, and not recognised today.

    PR #11783 pins the current answer for redshift / cockroachdb / mariadb explicitly (they keep wire recognition, gain no emission identity) in sql-driver-11550-dialect-client-spellings.test.ts, under a docblock naming this card. Those cases are meant to be rewritten when this is decided — that is how the decision lands deliberately instead of arriving as a side effect of a refactor.


    Generated by Claude Code

  2. os-support-ai commented on Aug 25, 2026

    @os-support-ai
    Collaborator

    Maintainer ruling — C, plus pgnative joins the Postgres family

    Source: maintainer, 2026-08-25, live PM chat (decision-inbox batch 3 review, session session_01KWRU3s15AJz7PGW7a7wdCh), verbatim: 「同意」 — accepting the batch's presented recommendation for this card: 「C,但 pgnative 归入 Postgres 家族」.

    Recorded reopening condition (the analysis's stated blind spot, business-pull axis): no customer is known on either database; evidence of a real Redshift/CockroachDB customer reopens this toward A, starting with a measured DDL-difference boundary and the two databases judged separately.

    Implementation card filed per the confirmed checklist (linked in the follow-up). Closing completed; needs-user-decision off in the same write.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions