diff --git a/.gitignore b/.gitignore index a852aee..2a170a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ node_modules/ *.log -output/*.sql -output/*.json .DS_Store .idea/ *.swp diff --git a/converter.js b/converter.js index 27bd4a2..a66a345 100644 --- a/converter.js +++ b/converter.js @@ -42,6 +42,8 @@ class PG2DMConverter { */ convertDataTypes(sql) { let converted = sql; + + // 1. 转换基本类型 const typePattern = /\b(int8|int4|int2|numeric|bool)\b/gi; converted = converted.replace(typePattern, (match) => { @@ -53,6 +55,14 @@ class PG2DMConverter { return match; }); + // 2. 处理timestamp精度参数 + // PostgreSQL: timestamp(6) 或 timestamp(0) + // 达梦: TIMESTAMP (不支持精度参数,直接移除) + converted = converted.replace(/\btimestamp\s*\(\s*\d+\s*\)/gi, (match) => { + this.log(`移除timestamp精度参数: ${match} -> TIMESTAMP`); + return `TIMESTAMP`; + }); + return converted; } @@ -167,6 +177,10 @@ class PG2DMConverter { removeTypeQuotes(sql) { let converted = sql; + // 先统一小写的text类型为TEXT(避免和"text_ops"操作符混淆) + converted = converted.replace(/\s+text\s+/gi, ' TEXT '); + converted = converted.replace(/\s+text([,\n\r])/gi, ' TEXT$1'); + // 移除引号中的数据类型(达梦不需要给类型加引号) // 必须在独立的步骤中处理,确保不会误伤列名 // 匹配模式:前面有空格,后面有空格或逗号 @@ -180,6 +194,25 @@ class PG2DMConverter { return converted; } + /** + * 移除空的或不完整的PARTITION BY子句 + */ + removeEmptyPartition(sql) { + let converted = sql; + + // 移除空的PARTITION BY子句 + // 格式1: )\nPARTITION BY (\n)\n; + // 格式2: ) PARTITION BY (); + converted = converted.replace(/\)\s*PARTITION\s+BY\s+\([^)]*\)\s*;/gi, ');\n'); + + const matches = sql.match(/PARTITION\s+BY\s+\(/gi); + if (matches) { + this.log(`移除 ${matches.length} 个空的PARTITION BY子句`); + } + + return converted; + } + /** * 简化索引语法 */ @@ -345,19 +378,23 @@ class PG2DMConverter { this.log('步骤6: 移除数据类型引号...'); converted = this.removeTypeQuotes(converted); - // 7. 简化索引语法 - this.log('步骤7: 简化索引语法...'); + // 7. 移除空的PARTITION BY子句 + this.log('步骤7: 移除空的PARTITION BY子句...'); + converted = this.removeEmptyPartition(converted); + + // 8. 简化索引语法 + this.log('步骤8: 简化索引语法...'); converted = this.simplifyIndexSyntax(converted); - // 8. 移除索引中的重复列 - this.log('步骤8: 移除索引中的重复列...'); + // 9. 移除索引中的重复列 + this.log('步骤9: 移除索引中的重复列...'); converted = this.removeDuplicateIndexColumns(converted); - // 9. 处理COALESCE函数索引 - this.log('步骤9: 处理COALESCE函数索引...'); + // 10. 处理COALESCE函数索引 + this.log('步骤10: 处理COALESCE函数索引...'); converted = this.processCoalesceIndexes(converted); - // 10. 添加转换说明 + // 11. 添加转换说明 if (config.output.addConversionComment) { converted = this.addConversionHeader(converted, originalFile); }