Statement 1: CREATE TABLE - [blocker] ddl.table.name.keyword.forbid: table name "select" is a reserved keyword - [blocker] ddl.table.engine.allowlist: engine MyISAM is not in allowlist [InnoDB] - [blocker] ddl.table.charset.allowlist: charset latin1 is not in allowlist [utf8mb4] - [blocker] ddl.table.foreign_key.forbid: foreign keys are forbidden - [blocker] ddl.table.primary_key.not_null.require: primary key column "bad_varchar" is nullable - [blocker] ddl.column.name.keyword.forbid: column name "select" is a reserved keyword - [blocker] ddl.column.name.max_length: column name exceeds 64 characters - [blocker] ddl.column.charset.allowlist: column charset latin1 is not in allowlist [utf8mb4] - [blocker] ddl.column.varchar.max_length: VARCHAR(32) exceeds max length limit - [warning] ddl.column.blob_text.forbid: TEXT type is forbidden - [warning] ddl.column.json.forbid: JSON type is forbidden - [warning] ddl.column.bit.forbid: BIT type is forbidden - [warning] ddl.column.timestamp.forbid: TIMESTAMP type is forbidden - [warning] ddl.column.float_double.forbid: DOUBLE type is forbidden - [warning] ddl.column.comment.require: column must have a comment - [warning] ddl.column.default.require: column "no_default" should define a default value - [warning] ddl.table.audit_columns.require: missing audit columns (created_at, updated_at) - [warning] ddl.table.comment.max_length: table comment exceeds max length limit - [warning] ddl.index.duplicate.forbid: index "baddup" duplicates "badleft" on (bad_varchar) - [warning] ddl.index.redundant_left_prefix.forbid: index is left-prefix redundant - [warning] ddl.constraint.primary_key.name.prefix.require: constraint "badpk" missing prefix "pk_"
Statement 1: CREATE TABLE - [blocker] ddl.table.name.keyword.forbid: table name "select" is a reserved keyword - [blocker] ddl.column.name.keyword.forbid: column name "select" is a reserved keyword - [blocker] ddl.column.name.max_length: column name exceeds 64 characters - [blocker] ddl.table.columns.min_count: table has fewer than 12 columns - [warning] ddl.column.blob_text.forbid: TEXT type is forbidden - [warning] ddl.column.comment.require: column must have a comment - [warning] ddl.column.default.require: column "no_default" should define a default value - [warning] ddl.column.not_null.require: column "nullable_col" should be NOT NULL - [warning] ddl.table.audit_columns.require: missing audit columns (created_at, updated_at) - [warning] ddl.table.comment.require: table must have a comment - [warning] ddl.constraint.primary_key.name.prefix.require: constraint "badpk" missing prefix "pk_" - [warning] ddl.constraint.unique_key.name.prefix.require: constraint "baduk" missing prefix "uk_"
注意 PostgreSQL 没有 ENGINE/CHARSET/ROW_FORMAT 概念,DeltaScope 会自动跳过这些 MySQL 专属规则,只检查 PG 适用的规则。
PostgreSQL:ALTER TABLE 方言专属风险
PostgreSQL 的 ALTER TABLE 有一些 MySQL 不存在的特殊风险,DeltaScope 针对性地提供了专属规则:
Statement 1: ALTER TABLE - [blocker] ddl.pg.alter.drop_column.advisory: dropping a column in PostgreSQL does not reclaim disk space; consider creating a new table without the column instead
PostgreSQL 的 DROP COLUMN 只是标记列为不可见,不会释放磁盘空间。对于大表,正确的做法是新建表并迁移数据。
ADD COLUMN NOT NULL 无 DEFAULT——全表重写:
1
deltascope audit --dialect postgresql --sql "alter table users add column bio text not null"
Statement 1: ALTER TABLE - [warning] ddl.pg.alter.add_column.non_null_no_default.warn: adding a NOT NULL column without a DEFAULT requires a full table rewrite in PostgreSQL
{ "verdict":"review", "summary":{"statements":3,"blockers":0,"warnings":4,"notices":0}, "explanation":{ "summary":"Audit produced 4 finding(s) across 3 statement(s)", "reasons":[ "column `id` must have a comment", "column `name` must have a comment", "column `price` must have a comment", "column `discount` must have a comment" ] }, "statements":[ { "index":0, "kind":"ddl", "raw_sql":"CREATE TABLE products (...)", "findings":[ { "rule_id":"ddl.column.comment.require", "level":"warning", "message":"column `id` must have a comment", "suggestion":"Add a COMMENT clause to column `id`", "location":{"line":2,"column":3} } ] }, { "index":1, "kind":"ddl", "raw_sql":"ALTER TABLE orders ADD COLUMN discount DECIMAL(10,2)", "findings":[ { "rule_id":"ddl.column.comment.require", "level":"warning", "message":"column `discount` must have a comment", "suggestion":"Add a COMMENT clause to column `discount`", "location":{"line":1,"column":38} } ] }, { "index":2, "kind":"dml", "raw_sql":"DELETE FROM audit_log WHERE created_at < '2020-01-01'" } ] }
3 条语句,4 个 warning,全部指向注释缺失。第 3 条 DELETE 因为有 WHERE 子句,顺利通过。
DML 影响行数估算
在元数据感知模式下,DeltaScope 还能估算 DML 的影响范围:
1 2
deltascope audit --sql "delete from users where id = 42" \ --host 127.0.0.1 --port 3306 --user root --ask-password --schema app