<feature>[ai] ZSTAC-84025: schema + SDK actions for inference template auto-match#3891
<feature>[ai] ZSTAC-84025: schema + SDK actions for inference template auto-match#3891zstack-robot-2 wants to merge 7 commits into5.5.22from
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Walkthrough该 PR 为 ModelVO 添加 pipelineTag 与 manifestJson;为 ModelServiceRefVO 添加 isDefault、lastOpDate 与 createDate(含回填并改为 NOT NULL 默认 '2000-01-01 00:00:00');新增测试 ApiHelper 的 autoMatchModelServiceByModel 方法;添加错误码常量 ORG_ZSTACK_AI_10166。 改动数据库 Schema 与测试支持
代码审查工作量估计🎯 3 (Moderate) | ⏱️ ~20 分钟 诗
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@conf/db/upgrade/V5.5.22__schema.sql`:
- Line 17: 将 ALTER TABLE for `ModelServiceRefVO` 的 `createDate` 列默认值从
'0000-00-00 00:00:00' 改为 DEFAULT CURRENT_TIMESTAMP,并在修改列约束为 NOT NULL
之前为历史行回填合理时间:实现一个短小的存储过程/函数(例如
backfill_model_service_ref_create_date)在升级脚本中先查找并将所有旧值(NULL 或 '0000-00-00
00:00:00')更新为合适的时间戳(如 NOW() 或基于业务规则的时间),执行完回填后再运行 ALTER TABLE 修改列定义为 NOT NULL
DEFAULT CURRENT_TIMESTAMP,以确保在严格模式下升级不会失败并保留历史数据一致性。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml (via .coderabbit.yaml)
Review profile: CHILL
Plan: Pro
Run ID: 457b51f9-3708-456c-b9b3-493701424bf5
⛔ Files ignored due to path filters (3)
sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelAction.javais excluded by!sdk/**sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelResult.javais excluded by!sdk/**sdk/src/main/java/org/zstack/sdk/UpdateModelAction.javais excluded by!sdk/**
📒 Files selected for processing (2)
conf/db/upgrade/V5.5.22__schema.sqltestlib/src/main/java/org/zstack/testlib/ApiHelper.groovy
…erviceRefVO.isDefault/createDate/lastOpDate Resolves: ZSTAC-84025 Change-Id: Ifbb68c9d475aa19762bb053e6545381a305dfe5b
…l.defaultModelServiceUuid Resolves: ZSTAC-84025 Change-Id: I4046976b0c4437ba4c14069946b8075393f152ed
…Model DSL Resolves: ZSTAC-84025 Change-Id: I0df26f7367a28da9c6c825dcddcb829db133374e
Resolves: ZSTAC-84025 Change-Id: I7a6c657369736978676164676b616b626d707974
8ccf27b to
23cb764
Compare
Review found the new ModelServiceRefVO createDate column used a zero-date default, which is unsafe under strict SQL mode. The upgrade now adds the column as nullable, backfills existing rows, then tightens it to NOT NULL with CURRENT_TIMESTAMP. This also adds the shared AI error code consumed by the premium review fix. Constraint: Premium branch references CloudOperationsErrorCode from zstack utils Rejected: Keep zero-date default | fails SQL coding rules and strict-mode upgrades Confidence: high Scope-risk: narrow Tested: JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 mvn -pl utils -DskipTests install Tested: JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 mvn -pl sdk -DskipTests install Not-tested: Full database migration against a live strict-mode MySQL instance Resolves: ZSTAC-84025 Change-Id: Ic0a63eec1e3db23e4bb8843efd8e2aee143dce21
There was a problem hiding this comment.
🧹 Nitpick comments (1)
conf/db/upgrade/V5.5.22__schema.sql (1)
5-8: 💤 Low value第 8 行的 UPDATE 语句是冗余的
当使用
ADD COLUMN ... NOT NULL DEFAULT 0时,MySQL 会自动将所有现有行的值设置为默认值 0。第 8 行的UPDATE ... SET isDefault = 0实际上是多余的操作。♻️ 建议移除冗余的 UPDATE 语句
-- ZSTAC-84025: Add isDefault to ModelServiceRefVO to mark the default inference template per model ALTER TABLE `zstack`.`ModelServiceRefVO` ADD COLUMN `isDefault` TINYINT(1) NOT NULL DEFAULT 0; - --- Backfill isDefault: all existing refs default to 0 (no default template designated) -UPDATE `zstack`.`ModelServiceRefVO` SET `isDefault` = 0;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@conf/db/upgrade/V5.5.22__schema.sql` around lines 5 - 8, The UPDATE statement on ModelServiceRefVO is redundant because ADD COLUMN `isDefault` TINYINT(1) NOT NULL DEFAULT 0 already sets existing rows to 0; remove the line "UPDATE `zstack`.`ModelServiceRefVO` SET `isDefault` = 0;" from V5.5.22__schema.sql and keep only the ALTER TABLE adding the `isDefault` column so the migration is idempotent and avoids unnecessary writes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@conf/db/upgrade/V5.5.22__schema.sql`:
- Around line 5-8: The UPDATE statement on ModelServiceRefVO is redundant
because ADD COLUMN `isDefault` TINYINT(1) NOT NULL DEFAULT 0 already sets
existing rows to 0; remove the line "UPDATE `zstack`.`ModelServiceRefVO` SET
`isDefault` = 0;" from V5.5.22__schema.sql and keep only the ALTER TABLE adding
the `isDefault` column so the migration is idempotent and avoids unnecessary
writes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml (via .coderabbit.yaml)
Review profile: CHILL
Plan: Pro
Run ID: 4adbb112-679e-4a10-9d98-e95a5f4e05fb
📒 Files selected for processing (2)
conf/db/upgrade/V5.5.22__schema.sqlutils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java
CI hit MySQL error 1293 because ModelServiceRefVO.lastOpDate already uses TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, and older MySQL/MariaDB versions allow only one automatic TIMESTAMP column per table. Keep createDate non-zero with a fixed default while the migration backfills existing rows with CURRENT_TIMESTAMP and premium ModelServiceRefVO prePersist sets real creation time for new JPA inserts. Constraint: Older MySQL/MariaDB permits only one automatic TIMESTAMP column per table Rejected: DEFAULT CURRENT_TIMESTAMP on createDate | conflicts with lastOpDate automatic timestamp Confidence: high Scope-risk: narrow Tested: git diff --check Tested: rg createDate/current timestamp/default checks in V5.5.22__schema.sql Tested: JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 mvn -pl utils -DskipTests install Not-tested: Full Flyway migration against the CI MySQL image Resolves: ZSTAC-84025 Change-Id: I095a6818443441409c84988dafbb6c16ef5d8e54
Code review noted that adding ModelServiceRefVO.isDefault as NOT NULL DEFAULT 0 already initializes existing rows, so the immediate UPDATE to the same value only adds unnecessary migration work. The schema keeps the defaulted column and removes the redundant write.\n\nConstraint: MySQL initializes existing rows when adding a NOT NULL column with a DEFAULT\nRejected: Keep explicit UPDATE | unnecessary table write during upgrade\nConfidence: high\nScope-risk: narrow\nTested: git diff --check\nTested: rg check for redundant isDefault UPDATE and zero-date defaults in V5.5.22__schema.sql\nTested: JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 mvn -pl utils -DskipTests install\nNot-tested: Full Flyway migration against CI database image Resolves: ZSTAC-84025 Change-Id: I062d884ed6232fa603a6ecfd68c2124db85c5ed6
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@conf/db/upgrade/V5.5.22__schema.sql`:
- Around line 28-31: The schema uses a sentinel default '2000-01-01 00:00:00'
for ModelServiceRefVO.createDate based on an outdated MySQL limitation; change
the column definition to use DEFAULT CURRENT_TIMESTAMP (keeping NOT NULL) so new
rows get the actual DB timestamp, and update any logic that assumes the sentinel
(including ModelServiceRefVO.@PrePersist) to tolerate/avoid relying on the
sentinel value—ensure the ALTER TABLE for ModelServiceRefVO modifies createDate
to TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP and verify `@PrePersist` does not
overwrite or depend on a pre-set sentinel.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml (via .coderabbit.yaml)
Review profile: CHILL
Plan: Pro
Run ID: b3428cf6-387d-436f-9ab0-cc48d4d2c0f4
📒 Files selected for processing (1)
conf/db/upgrade/V5.5.22__schema.sql
| -- Older MySQL/MariaDB versions allow only one TIMESTAMP column with CURRENT_TIMESTAMP | ||
| -- in DEFAULT or ON UPDATE. lastOpDate already uses it, so keep createDate non-zero | ||
| -- and let ModelServiceRefVO.@PrePersist populate the real creation time for new rows. | ||
| ALTER TABLE `zstack`.`ModelServiceRefVO` MODIFY COLUMN `createDate` TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 在 ZStack 代码库中搜索 MySQL 最低版本要求的声明
rg -rn --type=xml --type=properties --type=txt -i "mysql.*version|minimum.*mysql|mariadb.*version" \
-g '!**/target/**' -g '!**/node_modules/**' | head -40
# 也检查 pom.xml 或 build 配置中对 mysql-connector 的版本约束
rg -rn "mysql-connector|mysql.version" --type=xml | head -20Repository: MatheMatrix/zstack
Length of output: 222
🏁 Script executed:
#!/bin/bash
# Search for MySQL version requirements in documentation and config files
echo "=== Searching for MySQL version mentions in README and docs ==="
fd -e md -e txt . | xargs rg -l "mysql\|mariadb" -i | head -10 | while read f; do
echo "File: $f"
rg -C 3 "version|5\.[0-9]\.[0-9]" -i "$f" | head -20
done
echo "=== Searching in pom.xml for mysql-connector version ==="
fd pom.xml | xargs cat | rg -A 5 -B 5 "mysql-connector|mysql.*version" -iRepository: MatheMatrix/zstack
Length of output: 1304
🌐 Web query:
MySQL 5.6.5 TIMESTAMP CURRENT_TIMESTAMP multiple columns restriction history
💡 Result:
In MySQL 5.6.5 and later, you can have multiple TIMESTAMP columns in the same table that use the special automatic clauses DEFAULT CURRENT_TIMESTAMP and/or ON UPDATE CURRENT_TIMESTAMP; this restriction (only one TIMESTAMP column per table could have those automatic properties) was lifted in MySQL 5.6.5 [1][2]. What the “restriction history” looks like - Before 5.6.5, at most one TIMESTAMP column per table could be automatically initialized or updated to the current date and time; attempting to use CURRENT_TIMESTAMP defaults/updates on more than one TIMESTAMP column would fail (or be disallowed by the server/UI), depending on context [1][3]. - In MySQL 5.6.5 (released 2012-04-10 per 5.6 release notes), “This restriction has been lifted. Any TIMESTAMP column definition can have any combination of DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses.” The same changelog text also notes that these clauses can now be used with DATETIME definitions [1]. - MySQL’s current documentation (the referenced “Automatic Initialization and Updating for TIMESTAMP and DATETIME” section) describes the modern rules: TIMESTAMP/DATETIME columns can be specified to have current-timestamp behavior for default and/or auto-update, and different columns can have different combinations [2]. Practical notes for your specific query - If you’re on MySQL 5.6.5+: you can define multiple columns like: - col1 TIMESTAMP DEFAULT CURRENT_TIMESTAMP - col2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP and MySQL will allow it [2][1]. - The server behavior is also affected by explicit_defaults_for_timestamp (documented): when it’s disabled, MySQL may implicitly apply DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP to the first TIMESTAMP column if neither is specified explicitly [2]. That’s not a “5.6.5 multiple columns restriction” anymore, but it can affect which columns end up with automatic defaults.
Citations:
- 1: https://stackoverflow.com/questions/4489548/why-there-can-be-only-one-timestamp-column-with-current-timestamp-in-default-cla
- 2: https://dev.mysql.com/doc/refman/en/timestamp-initialization.html
- 3: Issue with multiple columns having default CURRENT_TIMESTAMP preaction/Minion-Backend-mysql#24
🏁 Script executed:
#!/bin/bash
# Read the actual SQL file to verify the exact code and context
cat -n conf/db/upgrade/V5.5.22__schema.sqlRepository: MatheMatrix/zstack
Length of output: 2085
createDate 的哨兵默认值 '2000-01-01 00:00:00' 基于已过时的 MySQL 限制,应改为 CURRENT_TIMESTAMP
第 28–30 行的注释解释了不能使用 DEFAULT CURRENT_TIMESTAMP 的原因——"旧版 MySQL/MariaDB 每张表只允许一列 TIMESTAMP 使用 CURRENT_TIMESTAMP"。然而,MySQL 5.6.5(2012 年 4 月发布)已经取消了该限制,允许任意数量的 TIMESTAMP 列使用 DEFAULT CURRENT_TIMESTAMP 与 ON UPDATE CURRENT_TIMESTAMP 的任意组合。
ZStack 的 pom.xml 依赖 mysql-connector-j 8.2.0,明确表示项目针对 MySQL 8.x 开发和测试。这说明没有对 MySQL 5.6.5 之前版本的支持需求。因此,当前的 DEFAULT '2000-01-01 00:00:00' 绕过方案依据的前提已不成立。
该哨兵值带来的风险是:如果 ModelServiceRefVO.@PrePersist 因故障、异常或被绕过而无法执行,任何未显式设置 createDate 的新 INSERT 都会记录一个在 2000 年的错误时间戳,导致该行数据的时间信息彻底失真,难以在后续业务逻辑(如"挑选最早的 isDefault=true 行")中正确处理。
🛠️ 建议修复
-ALTER TABLE `zstack`.`ModelServiceRefVO` MODIFY COLUMN `createDate` TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00';
+ALTER TABLE `zstack`.`ModelServiceRefVO` MODIFY COLUMN `createDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| -- Older MySQL/MariaDB versions allow only one TIMESTAMP column with CURRENT_TIMESTAMP | |
| -- in DEFAULT or ON UPDATE. lastOpDate already uses it, so keep createDate non-zero | |
| -- and let ModelServiceRefVO.@PrePersist populate the real creation time for new rows. | |
| ALTER TABLE `zstack`.`ModelServiceRefVO` MODIFY COLUMN `createDate` TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'; | |
| -- Older MySQL/MariaDB versions allow only one TIMESTAMP column with CURRENT_TIMESTAMP | |
| -- in DEFAULT or ON UPDATE. lastOpDate already uses it, so keep createDate non-zero | |
| -- and let ModelServiceRefVO.@PrePersist populate the real creation time for new rows. | |
| ALTER TABLE `zstack`.`ModelServiceRefVO` MODIFY COLUMN `createDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@conf/db/upgrade/V5.5.22__schema.sql` around lines 28 - 31, The schema uses a
sentinel default '2000-01-01 00:00:00' for ModelServiceRefVO.createDate based on
an outdated MySQL limitation; change the column definition to use DEFAULT
CURRENT_TIMESTAMP (keeping NOT NULL) so new rows get the actual DB timestamp,
and update any logic that assumes the sentinel (including
ModelServiceRefVO.@PrePersist) to tolerate/avoid relying on the sentinel
value—ensure the ALTER TABLE for ModelServiceRefVO modifies createDate to
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP and verify `@PrePersist` does not
overwrite or depend on a pre-set sentinel.
There was a problem hiding this comment.
Comment from ye.zou:
这条建议我不采纳,当前改成非 CURRENT_TIMESTAMP 是为了兼容本分支实际验证环境里的 MySQL 5.7 行为:explicit_defaults_for_timestamp=OFF 时,lastOpDate 已带 ON UPDATE CURRENT_TIMESTAMP,再把 createDate 改为 DEFAULT CURRENT_TIMESTAMP 会直接触发本次失败日志里的错误:
Error Code : 1293 Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
另外 Java 侧 ModelServiceRefVO.@PrePersist 已在新行写入真实创建时间,2000-01-01 00:00:00 只是为了让历史/绕过 JPA 的插入不违反 NOT NULL,并不作为业务排序依赖。这个 schema 改动已经在本地 PR docker 跑过 AutoMatchModelServiceCase,可以通过该迁移阶段。
There was a problem hiding this comment.
@zstack-robot-2,感谢 ye.zou 的详细解释,完全理解了。在 MySQL 5.7 且 explicit_defaults_for_timestamp=OFF 的环境下,Error 1293 确实会重新生效——即便 MySQL 5.6.5 在标准模式下解除了该限制,该模式下的行为仍然是每表只允许一列 TIMESTAMP 使用 CURRENT_TIMESTAMP。lastOpDate 已占用该位,createDate 使用 '2000-01-01 00:00:00' 作为 NOT NULL 占位是正确的处理方式,撤回该建议。
✏️ Learnings added
Learnt from: zstack-robot-2
Repo: MatheMatrix/zstack PR: 3891
File: conf/db/upgrade/V5.5.22__schema.sql:28-31
Timestamp: 2026-05-07T09:44:01.429Z
Learning: In ZStack upgrade scripts (e.g., conf/db/upgrade/V5.5.22__schema.sql), when a table already has a TIMESTAMP column with `ON UPDATE CURRENT_TIMESTAMP` (e.g., `lastOpDate`), the second TIMESTAMP column (e.g., `createDate`) must NOT use `DEFAULT CURRENT_TIMESTAMP`. The validated environment runs MySQL 5.7 with `explicit_defaults_for_timestamp=OFF`, which reintroduces the Error 1293 restriction ("there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause") even though MySQL 5.6.5+ lifted it in standard mode. The intentional workaround is to use a sentinel default `'2000-01-01 00:00:00'` (NOT NULL) and rely on `ModelServiceRefVO.PrePersist` in Java to populate the real creation timestamp for new JPA-managed rows.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: zstack-robot-2
Repo: MatheMatrix/zstack PR: 3416
File: conf/db/upgrade/V5.5.12__schema.sql:24-35
Timestamp: 2026-03-05T02:13:23.339Z
Learning: In ZStack, the database schema name is fixed as 'zstack'. For SQL upgrade scripts under conf/db/upgrade, continue using TABLE_SCHEMA = 'zstack' and reference tables as zstack.`UsedIpVO` (i.e., qualify with the schema). Do not replace with DATABASE() or remove the schema qualifier for portability. This pattern can be assumed across upgrade scripts in this directory.
Scope (zstack core)
ZSTAC-84025 推理模板自动匹配 (Inference Template Auto-Match) for AIOS 5.5.22 — zstack core slice.
Changes (3 commits)
552558629aV5.5.22__schema.sql— addsModelVO.pipelineTag/manifestJson,ModelServiceRefVO.isDefault/createDate/lastOpDatee088888775AutoMatchModelServiceByModelAction/Result,UpdateModelAction.defaultModelServiceUuidfield8ccf27b358ApiHelper.groovyregenerated withautoMatchModelServiceByModelDSLCross-repo dependencies
This MR is one of three:
.ggufdetection + YAML frontmatter parser + manifest passthroughAll three must land together; premium's runtime depends on schema added here.
Verification
./runMavenProfile premiumBUILD SUCCESS in PR docker (full clean install, 1h45m)createDate DEFAULT '0000-00-00 00:00:00')Spec
sync from gitlab !9772