This commit is contained in:
dengqichen 2025-11-15 13:41:24 +08:00
parent aff0ac1d52
commit 1a182e879a
2 changed files with 44 additions and 9 deletions

2
.gitignore vendored
View File

@ -1,7 +1,5 @@
node_modules/ node_modules/
*.log *.log
output/*.sql
output/*.json
.DS_Store .DS_Store
.idea/ .idea/
*.swp *.swp

View File

@ -42,6 +42,8 @@ class PG2DMConverter {
*/ */
convertDataTypes(sql) { convertDataTypes(sql) {
let converted = sql; let converted = sql;
// 1. 转换基本类型
const typePattern = /\b(int8|int4|int2|numeric|bool)\b/gi; const typePattern = /\b(int8|int4|int2|numeric|bool)\b/gi;
converted = converted.replace(typePattern, (match) => { converted = converted.replace(typePattern, (match) => {
@ -53,6 +55,14 @@ class PG2DMConverter {
return match; 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; return converted;
} }
@ -167,6 +177,10 @@ class PG2DMConverter {
removeTypeQuotes(sql) { removeTypeQuotes(sql) {
let converted = 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; 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: 移除数据类型引号...'); this.log('步骤6: 移除数据类型引号...');
converted = this.removeTypeQuotes(converted); converted = this.removeTypeQuotes(converted);
// 7. 简化索引语法 // 7. 移除空的PARTITION BY子句
this.log('步骤7: 简化索引语法...'); this.log('步骤7: 移除空的PARTITION BY子句...');
converted = this.removeEmptyPartition(converted);
// 8. 简化索引语法
this.log('步骤8: 简化索引语法...');
converted = this.simplifyIndexSyntax(converted); converted = this.simplifyIndexSyntax(converted);
// 8. 移除索引中的重复列 // 9. 移除索引中的重复列
this.log('步骤8: 移除索引中的重复列...'); this.log('步骤9: 移除索引中的重复列...');
converted = this.removeDuplicateIndexColumns(converted); converted = this.removeDuplicateIndexColumns(converted);
// 9. 处理COALESCE函数索引 // 10. 处理COALESCE函数索引
this.log('步骤9: 处理COALESCE函数索引...'); this.log('步骤10: 处理COALESCE函数索引...');
converted = this.processCoalesceIndexes(converted); converted = this.processCoalesceIndexes(converted);
// 10. 添加转换说明 // 11. 添加转换说明
if (config.output.addConversionComment) { if (config.output.addConversionComment) {
converted = this.addConversionHeader(converted, originalFile); converted = this.addConversionHeader(converted, originalFile);
} }