Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
085fa8ac
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
085fa8ac
编写于
4月 19, 2004
作者:
B
Bruce Momjian
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update to my2pg 1.28, from:
http://www.omnistarinc.com/~fonin/downloads.php#my2pg
上级
52e4f27a
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
271 addition
and
216 deletion
+271
-216
contrib/mysql/my2pg.pl
contrib/mysql/my2pg.pl
+271
-216
未找到文件。
contrib/mysql/my2pg.pl
浏览文件 @
085fa8ac
...
...
@@ -35,17 +35,26 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $My2pg: my2pg.pl,v 1.2
7
2001/12/06 19:32:20 fonin Exp $
# $
PostgreSQL: pgsql/contrib/mysql/my2pg.pl,v 1.11 2003/11/29 22:39:26 pgsql
Exp $
# $My2pg: my2pg.pl,v 1.2
8
2001/12/06 19:32:20 fonin Exp $
# $
Id: my2pg.pl,v 1.12 2004/04/19 23:11:49 momjian
Exp $
#
# $Log: my2pg.pl,v $
# Revision 1.11 2003/11/29 22:39:26 pgsql
# Revision 1.12 2004/04/19 23:11:49 momjian
# Update to my2pg 1.28, from:
#
#
make sure the $Id tags are converted to $PostgreSQL as well ...
#
http://www.omnistarinc.com/~fonin/downloads.php#my2pg
#
# Revision 1.10 2003/01/07 22:18:43 momjian
# Upgrade to my2pg 1.9
# Revision 1.28 2002/11/30 12:03:48 fonin
# PostgreSQL does not support indexes on the partial length of column,
# e.g.
# CREATE INDEX i_index ON table (column(16));
# will not work. Fixed.
#
# Added command-line option -s that prevents my2pg from attempting convert
# the data (currently only timestamps).
#
# Better timestamps conversion.
#
# Revision 1.27 2002/07/16 14:54:07 fonin
# Bugfix - didn't quote the fields inside PRIMARY KEY with -d option.
...
...
@@ -162,7 +171,7 @@ my $chareg=''; # CHAR conversion regexps
my
$dq
=
'';
# double quote
# parse command line
getopts
('
nhd
',
\
%opts
);
getopts
('
nhd
s
',
\
%opts
);
# output syntax
if
(
$opts
{
h
}
ne
'')
{
...
...
@@ -179,10 +188,17 @@ if($opts{d} ne '') {
$dq
=
'
"
';
}
if
(
$opts
{
s} ne '') {
$safe_data_conv=1;
}
else {
$safe_data_conv=0;
}
$|
=
1
;
print
("
------------------------------------------------------------------
");
print
("
\n
-- My2Pg 1.2
7
translated dump
");
print
("
\n
-- My2Pg 1.2
8
translated dump
");
print
("
\n
--
");
print
("
\n
------------------------------------------------------------------
");
...
...
@@ -213,86 +229,86 @@ print LIBTYPES "\n#define ADD_COMMA if(strcmp(result,\"\")!=0) strcat(result,\",
# reading STDIN...
my
$tabledef
=
0
;
# we are outside a table definition
while
(
<>
)
{
if
(
!
$tabledef
&&
/^CREATE TABLE \S+/i
){
$tabledef
=
1
;
}
elsif
(
$tabledef
&&
/^\) type=\w*;/i
){
# /^\w/i
$tabledef
=
0
;
}
if
(
!
$tabledef
&&
/^CREATE TABLE \S+/i
){
$tabledef
=
1
;
}
elsif
(
$tabledef
&&
/^\) type=\w*;/i
){
# /^\w/i
$tabledef
=
0
;
}
# Comments start with -- in SQL
if
(
/^#/
)
{
# !/insert into.*\(.*#.*\)/i, in mysqldump output
s/#/--/
;
}
if
(
$tabledef
){
##################################
if
(
$tabledef
)
{
# Convert numeric types
s/tinyint\(\d+\)/INT2/i
;
s/smallint\(\d+\)/INT2/i
;
s/mediumint\(\d+\)/INT4/i
;
s/bigint\(\d+\)/INT8/i
;
s/int\(\d+\)/INT4/i
;
s/float(\(\d+,\d*\))/DECIMAL$1/i
;
s/double precision/FLOAT8 /i
;
s/([\W])double(\(\d+,\d*\))/$1DECIMAL$2/i
;
s/([\W])double[\W]/$1FLOAT8 /i
;
s/([\W])real[\W]/$1FLOAT8 /i
;
s/([\W])real(\(\d+,\d*\))/$1DECIMAL$2/i
;
s/tinyint\(\d+\)/INT2/i
;
s/smallint\(\d+\)/INT2/i
;
s/mediumint\(\d+\)/INT4/i
;
s/bigint\(\d+\)/INT8/i
;
s/int\(\d+\)/INT4/i
;
s/float(\(\d+,\d*\))/DECIMAL$1/i
;
s/double precision/FLOAT8 /i
;
s/([\W])double(\(\d+,\d*\))/$1DECIMAL$2/i
;
s/([\W])double[\W]/$1FLOAT8 /i
;
s/([\W])real[\W]/$1FLOAT8 /i
;
s/([\W])real(\(\d+,\d*\))/$1DECIMAL$2/i
;
# Convert string types
s/\w*blob$chareg/text/i
;
s/mediumtext$chareg/text/i
;
s/tinytext$chareg/text/i
;
s/\stext\s+not\s+null/ TEXT DEFAULT '' NOT NULL/i
;
s/(.*?char\(.*?\))$chareg/$1/i
;
s/\w*blob$chareg/text/i
;
s/mediumtext$chareg/text/i
;
s/tinytext$chareg/text/i
;
s/\stext\s+not\s+null/ TEXT DEFAULT '' NOT NULL/i
;
s/(.*?char\(.*?\))$chareg/$1/i
;
# Old and New are reserved words in Postgres
s/^(\s+)Old /${1}MyOld /
;
s/^(\s+)New /${1}MyNew /
;
s/^(\s+)Old /${1}MyOld /
;
s/^(\s+)New /${1}MyNew /
;
# Convert DATE types
s/datetime/TIMESTAMP/
;
s/timestamp\(\d+\)/TIMESTAMP/i
;
s/ date / DATE /i
;
s/,(\d{4})(\d{2})(\d{2}),/,'$1-$2-$3 00:00:00',/g
;
s/datetime/TIMESTAMP/
;
s/timestamp\(\d+\)/TIMESTAMP/i
;
s/ date / DATE /i
;
if
((
/date/ig
||
/time/ig
)
&&
/[,(]\d{4}(\d{2})(\d{2})[,)]/
&&
$
1
>=
0
&&
$
1
<=
12
&&
$
2
>=
0
&&
$
2
<=
31
)
{
s/,(\d{4})(\d{2})(\d{2}),/,'$1-$2-$3 00:00:00',/g
;
}
# small hack - convert "default" to uppercase, because below we
# enclose all lowercase words in double quotes
if
(
!
/^INSERT/
)
{
s/default/DEFAULT/
;
}
if
(
!
/^INSERT/
)
{
s/default/DEFAULT/
;
}
# Change all AUTO_INCREMENT fields to SERIAL ones with a pre-defined sequence
if
(
/([\w\d]+)\sint.*auto_increment/i
)
{
$tmpseq
=
new_name
("
$table_name
"
.
"
_
"
.
"
$+
"
.
"
_SEQ
",
28
);
$seq
{
$table_name
}
=
$tmpseq
;
$primary
{
$table_name
}
=
$+
;
s/(int.*?) .*AUTO_INCREMENT/$1 DEFAULT nextval\('$tmpseq'\)/i
;
#s/(int.*?)DEFAULT\s*?'.*?'(.*?)AUTO_INCREMENT/$1$2DEFAULT nextval\('$tmpseq'\)/i;
}
if
(
/([\w\d]+)\sint.*auto_increment/i
)
{
$tmpseq
=
new_name
("
$table_name
"
.
"
_
"
.
"
$+
"
.
"
_SEQ
",
28
);
$seq
{
$table_name
}
=
$tmpseq
;
$primary
{
$table_name
}
=
$+
;
s/(int.*?) .*AUTO_INCREMENT/$1 DEFAULT nextval\('$tmpseq'\)/i
;
}
# convert UNSIGNED to CHECK constraints
if
(
/^\s+?([\w\d_]+).*?unsigned/i
)
{
$check
.=
"
,
\n
CHECK (
$dq
$1
$dq
>=0)
";
}
s/unsigned//i
;
if
(
/^\s+?([\w\d_]+).*?unsigned/i
)
{
$check
.=
"
,
\n
CHECK (
$dq
$1
$dq
>=0)
";
}
s/unsigned//i
;
# Limited ENUM support - little heuristic
s/enum\('N','Y'\)/BOOL/i
;
s/enum\('Y','N'\)/BOOL/i
;
s/enum\('N','Y'\)/BOOL/i
;
s/enum\('Y','N'\)/BOOL/i
;
# ENUM support
if
(
/^\s+?([\w\d_]+).*?enum\((.*?)\)/i
)
{
my
$enumlist
=
$
2
;
my
@item
;
$item
[
0
]
=
'';
while
(
$enumlist
=~
s/'([\d\w_]+)'//i
)
{
$item
[
++
$#item
]
=
$
1
;
}
if
(
/^\s+?([\w\d_]+).*?enum\((.*?)\)/i
)
{
my
$enumlist
=
$
2
;
my
@item
;
$item
[
0
]
=
'';
while
(
$enumlist
=~
s/'([\d\w_]+)'//i
)
{
$item
[
++
$#item
]
=
$
1
;
}
# forming identifier name
$typename
=
new_name
('
enum_
'
.
$table_name
.
'
_
'
.
$item
[
1
],
28
);
# $typename=lc('enum_'.$table_name.'_'.$item[1]);
$typename
=
new_name
('
enum_
'
.
$table_name
.
'
_
'
.
$item
[
1
],
28
);
# creating input type function
my
$func_in
=
"
my
$func_in
=
"
int2*
$typename
"
.
"
_in (char *str) {
int2* result;
...
...
@@ -301,34 +317,34 @@ int2* $typename"."_in (char *str) {
result=(int2*)palloc(sizeof(int2));
*result=-1;
";
for
(
my
$i
=
0
;
$i
<=
$#item
;
$i
++
)
{
$func_in
.=
"
for
(
my
$i
=
0
;
$i
<=
$#item
;
$i
++
)
{
$func_in
.=
"
if(strcmp(str,
\"
$item
[
$i
]
\"
)==0) {
*result=
$i
;
}
";
}
$func_in
.=
"
}
$func_in
.=
"
if(*result == -1) {
elog(ERROR,
\"
$typename
"
.
"
_in: incorrect input value
\"
);
return NULL;
}
return (result);
}
\n
";
$types
.=
"
\n
---
";
$types
.=
"
\n
--- Types for table
"
.
uc
(
$table_name
);
$types
.=
"
\n
---
\n
";
print
LIBTYPES
"
\n
/*
";
print
LIBTYPES
"
\n
* Types for table
"
.
uc
(
$table_name
);
print
LIBTYPES
"
\n
*/
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_in (opaque)
$types
.=
"
\n
---
";
$types
.=
"
\n
--- Types for table
"
.
uc
(
$table_name
);
$types
.=
"
\n
---
\n
";
print
LIBTYPES
"
\n
/*
";
print
LIBTYPES
"
\n
* Types for table
"
.
uc
(
$table_name
);
print
LIBTYPES
"
\n
*/
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_in (opaque)
RETURNS
$typename
AS '
$libtypename
'
LANGUAGE 'c'
WITH (ISCACHABLE);
\n
";
# creating output function
my
$func_out
=
"
my
$func_out
=
"
char*
$typename
"
.
"
_out (int2 *outvalue) {
char* result;
...
...
@@ -337,13 +353,13 @@ char* $typename"."_out (int2 *outvalue) {
result=(char*)palloc(10);
switch (*outvalue) {
";
for
(
my
$i
=
0
;
$i
<=
$#item
;
$i
++
)
{
$func_out
.=
"
for
(
my
$i
=
0
;
$i
<=
$#item
;
$i
++
)
{
$func_out
.=
"
case
$i
:
strcpy(result,
\"
$item
[
$i
]
\"
);
break;
";
}
$func_out
.=
"
}
$func_out
.=
"
default :
elog(ERROR,
\"
$typename
"
.
"
_out: incorrect stored value
\"
);
return NULL;
...
...
@@ -351,7 +367,7 @@ char* $typename"."_out (int2 *outvalue) {
}
return result;
}
\n
";
$func_out
.=
"
\n
bool
$typename
"
.
"
_eq(int2* a, int2* b) {
$func_out
.=
"
\n
bool
$typename
"
.
"
_eq(int2* a, int2* b) {
return (*a==*b);
}
...
...
@@ -375,19 +391,19 @@ bool $typename"."_ge(int2* a, int2* b) {
return (*a>=*b);
}
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_out (opaque)
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_out (opaque)
RETURNS opaque
AS '
$libtypename
'
LANGUAGE 'c'
WITH (ISCACHABLE);
\n
";
$types
.=
"
\n
CREATE TYPE
$typename
(
$types
.=
"
\n
CREATE TYPE
$typename
(
internallength = 2,
input =
$typename
\
_in,
output =
$typename
\
_out
);
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_eq (
$typename
,
$typename
)
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_eq (
$typename
,
$typename
)
RETURNS bool
AS '
$libtypename
'
LANGUAGE 'c';
...
...
@@ -460,32 +476,31 @@ CREATE OPERATOR <> (
procedure =
$typename
"
.
"
_ne
);
\n
";
print
LIBTYPES
$func_in
;
print
LIBTYPES
$func_out
;
s/enum\(.*?\)/$typename/i
;
}
print
LIBTYPES
$func_in
;
print
LIBTYPES
$func_out
;
s/enum\(.*?\)/$typename/i
;
}
# SET support
if
(
/^\s+?([\w\d_]+).*?set\((.*?)\)/i
)
{
my
$setlist
=
$
2
;
my
@item
;
$item
[
0
]
=
'';
my
$maxlen
=
0
;
# maximal string length
while
(
$setlist
=~
s/'([\d\w_]+)'//i
)
{
$item
[
++
$#item
]
=
$
1
;
$maxlen
+=
length
(
$item
[
$#item
])
+
1
;
}
$maxlen
+=
1
;
my
$typesize
=
int
(
$#item
/
8
);
if
(
$typesize
<
2
)
{
$typesize
=
2
;
}
$internalsize
=
$typesize
;
$typesize
=
'
int
'
.
$typesize
;
# $typename=lc('set_'.$table_name.'_'.$item[1]);
$typename
=
new_name
('
set_
'
.
$table_name
.
'
_
'
.
$item
[
1
],
28
);
if
(
/^\s+?([\w\d_]+).*?set\((.*?)\)/i
)
{
my
$setlist
=
$
2
;
my
@item
;
$item
[
0
]
=
'';
my
$maxlen
=
0
;
# maximal string length
while
(
$setlist
=~
s/'([\d\w_]+)'//i
)
{
$item
[
++
$#item
]
=
$
1
;
$maxlen
+=
length
(
$item
[
$#item
])
+
1
;
}
$maxlen
+=
1
;
my
$typesize
=
int
(
$#item
/
8
);
if
(
$typesize
<
2
)
{
$typesize
=
2
;
}
$internalsize
=
$typesize
;
$typesize
=
'
int
'
.
$typesize
;
$typename
=
new_name
('
set_
'
.
$table_name
.
'
_
'
.
$item
[
1
],
28
);
# creating input type function
my
$func_in
=
"
my
$func_in
=
"
$typesize
*
$typename
"
.
"
_in (char *str) {
$typesize
* result;
char* token;
...
...
@@ -498,14 +513,14 @@ $typesize* $typename"."_in (char *str) {
if(strcmp(str,
\"\"
)==0)
return result;
for(token=strtok(str,
\"
,
\"
);token!=NULL;token=strtok(NULL,
\"
,
\"
)) {
";
for
(
my
$i
=
0
,
my
$j
=
1
;
$i
<=
$#item
;
$i
++
,
$j
*=
2
)
{
$func_in
.=
"
for
(
my
$i
=
0
,
my
$j
=
1
;
$i
<=
$#item
;
$i
++
,
$j
*=
2
)
{
$func_in
.=
"
if(strcmp(token,
\"
$item
[
$i
]
\"
)==0) {
*result|=
$j
;
continue;
}
";
}
$func_in
.=
"
}
$func_in
.=
"
}
if(*result == 0) {
...
...
@@ -515,20 +530,20 @@ $typesize* $typename"."_in (char *str) {
return (result);
}
\n
";
$types
.=
"
\n
---
";
$types
.=
"
\n
--- Types for table
"
.
uc
(
$table_name
);
$types
.=
"
\n
---
\n
";
print
LIBTYPES
"
\n
/*
";
print
LIBTYPES
"
\n
* Types for table
"
.
uc
(
$table_name
);
print
LIBTYPES
"
\n
*/
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_in (opaque)
$types
.=
"
\n
---
";
$types
.=
"
\n
--- Types for table
"
.
uc
(
$table_name
);
$types
.=
"
\n
---
\n
";
print
LIBTYPES
"
\n
/*
";
print
LIBTYPES
"
\n
* Types for table
"
.
uc
(
$table_name
);
print
LIBTYPES
"
\n
*/
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_in (opaque)
RETURNS
$typename
AS '
$libtypename
'
LANGUAGE 'c';
\n
";
# creating output function
my
$func_out
=
"
my
$func_out
=
"
char*
$typename
"
.
"
_out (
$typesize
*outvalue) {
char* result;
int i;
...
...
@@ -540,16 +555,16 @@ char* $typename"."_out ($typesize *outvalue) {
strcpy(result,
\"\"
);
for(i=1;i<=2 << (sizeof(int2)*8);i*=2) {
switch (*outvalue & i) {
";
for
(
my
$i
=
0
,
$j
=
1
;
$i
<=
$#item
;
$i
++
,
$j
*=
2
)
{
$func_out
.=
"
for
(
my
$i
=
0
,
$j
=
1
;
$i
<=
$#item
;
$i
++
,
$j
*=
2
)
{
$func_out
.=
"
case
$j
:
";
if
(
$item
[
$i
]
ne
'')
{
$func_out
.=
"
ADD_COMMA;
";
}
$func_out
.=
"
strcat(result,
\"
$item
[
$i
]
\"
);
if
(
$item
[
$i
]
ne
'')
{
$func_out
.=
"
ADD_COMMA;
";
}
$func_out
.=
"
strcat(result,
\"
$item
[
$i
]
\"
);
break;
";
}
$func_out
.=
"
}
$func_out
.=
"
default :
break;
}
...
...
@@ -557,7 +572,7 @@ char* $typename"."_out ($typesize *outvalue) {
return result;
}
\n
";
$func_out
.=
"
\n
bool
$typename
"
.
"
_eq(
$typesize
* a,
$typesize
* b) {
$func_out
.=
"
\n
bool
$typename
"
.
"
_eq(
$typesize
* a,
$typesize
* b) {
return (*a==*b);
}
...
...
@@ -574,18 +589,18 @@ $typesize find_in_set($typesize *a, $typesize *b) {
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_out (opaque)
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_out (opaque)
RETURNS opaque
AS '
$libtypename
'
LANGUAGE 'c';
\n
";
$types
.=
"
\n
CREATE TYPE
$typename
(
$types
.=
"
\n
CREATE TYPE
$typename
(
internallength =
$internalsize
,
input =
$typename
\
_in,
output =
$typename
\
_out
);
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_eq (
$typename
,
$typename
)
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_eq (
$typename
,
$typename
)
RETURNS bool
AS '
$libtypename
'
LANGUAGE 'c';
...
...
@@ -612,10 +627,10 @@ CREATE OPERATOR <> (
\n
";
print
LIBTYPES
$func_in
;
print
LIBTYPES
$func_out
;
s/set\(.*?\)/$typename/i
;
}
print
LIBTYPES
$func_in
;
print
LIBTYPES
$func_out
;
s/set\(.*?\)/$typename/i
;
}
# Change multy-field keys to multi-field indices
# MySQL Dump usually ends the CREATE TABLE statement like this:
...
...
@@ -632,71 +647,80 @@ CREATE OPERATOR <> (
# );
# CREATE INDEX offer_id ON bids (offer_id,user_id,the_time);
# CREATE INDEX bid_value ON bids (bid_value);
if
(
s/CREATE TABLE (.*) /CREATE TABLE $dq$1$dq /i
)
{
if
(
$oldtable
ne
$table_name
)
{
$oldtable
=
$table_name
;
$j
=-
1
;
$check
=
'';
if
(
$seq
{
$table_name
}
ne
'')
{
print
"
\n\n
--
";
print
"
\n
-- Sequences for table
"
.
uc
(
$table_name
);
print
"
\n
--
\n
";
print
"
\n
CREATE SEQUENCE
"
.
$seq
{
$table_name
}
.
"
;
\n\n
";
}
print
$types
;
$types
=
'';
$dump
=~
s/,\n\).*;/\n\);/gmi
;
if
(
s/CREATE TABLE (.*) /CREATE TABLE $dq$1$dq /i
)
{
if
(
$oldtable
ne
$table_name
)
{
$oldtable
=
$table_name
;
$j
=-
1
;
$check
=
'';
if
(
$seq
{
$table_name
}
ne
'')
{
print
"
\n\n
--
";
print
"
\n
-- Sequences for table
"
.
uc
(
$table_name
);
print
"
\n
--
\n
";
print
"
\n
CREATE SEQUENCE
"
.
$seq
{
$table_name
}
.
"
;
\n\n
";
}
print
$types
;
$types
=
'';
$dump
=~
s/,\n\).*;/\n\);/gmi
;
# removing table options after closing bracket:
# ) TYPE=ISAM PACK_KEYS=1;
$dump
=~
s/\n\).*/\n\);/gmi
;
print
$dump
;
$dump
=
'';
}
$table_name
=
$
1
;
}
$dump
=~
s/\n\).*/\n\);/gmi
;
print
$dump
;
$dump
=
'';
}
$table_name
=
$
1
;
}
# output CHECK constraints instead UNSIGNED modifiers
if
(
/PRIMARY KEY\s+\((.*)\)/i
)
{
my
$tmpfld
=
$
1
;
$tmpfld
=~
s/,/","/g
if
$dq
;
$tmpfld
=~
s/ //g
;
s/PRIMARY KEY\s+(\(.*\))/PRIMARY KEY \($dq$tmpfld$dq\)/i
;
s/(PRIMARY KEY \(.*\)).*/$1$check\n/i
;
}
if
(
/PRIMARY KEY\s+\((.*)\)/i
)
{
my
$tmpfld
=
$
1
;
$tmpfld
=~
s/,/","/g
if
$dq
;
$tmpfld
=~
s/ //g
;
s/PRIMARY KEY\s+(\(.*\))/PRIMARY KEY \($dq$tmpfld$dq\)/i
;
s/(PRIMARY KEY \(.*\)).*/$1$check\n/i
;
}
if
(
/^\s*KEY ([\w\d_]+)\s*\((.*)\).*/i
)
{
my
$tmpfld
=
$
2
;
my
$ky
=
$
1
;
$tmpfld
=~
s/\s*,\s*/","/g
if
$dq
;
$index
{
$table_name
}[
++
$j
]
=
"
CREATE INDEX
${ky}
_
$table_name
\
_index ON
$dq$table_name$dq
(
$dq$tmpfld$dq
);
";
}
if
(
/^\s*UNIQUE.*?([\w\d_]+)\s*\((.*)\).*/i
)
{
my
$tmpfld
=
$
2
;
my
$ky
=
$
1
;
$tmpfld
=~
s/,/","/g
if
$dq
;
$index
{
$table_name
}[
++
$j
]
=
"
CREATE UNIQUE INDEX
${ky}
_
$table_name
\
_index ON
$dq$table_name$dq
(
$dq$tmpfld$dq
);
";
}
s/^\s*UNIQUE (.+).*(\(.*\)).*\n//i
;
s/^\s*KEY (.+).*(\(.*\)).*\n//i
;
if
(
/^\s*KEY ([\w\d_]+)\s*\((.*)\).*/i
)
{
my
$tmpfld
=
$
2
;
my
$ky
=
$
1
;
$tmpfld
=~
s/\s*,\s*/","/g
if
$dq
;
$tmpfld
=~
s/(\(\d+\))//g
;
$index
{
$table_name
}[
++
$j
]
=
"
CREATE INDEX
${ky}
_
$table_name
\
_index ON
$dq$table_name$dq
(
$dq$tmpfld$dq
);
";
}
if
(
/^\s*UNIQUE.*?([\w\d_]+)\s*\((.*)\).*/i
)
{
my
$tmpfld
=
$
2
;
my
$ky
=
$
1
;
$tmpfld
=~
s/,/","/g
if
$dq
;
$tmpfld
=~
s/(\(\d+\))//g
;
$index
{
$table_name
}[
++
$j
]
=
"
CREATE UNIQUE INDEX
${ky}
_
$table_name
\
_index ON
$dq$table_name$dq
(
$dq$tmpfld$dq
);
";
}
s/^\s*UNIQUE (.+).*(\(.*\)).*\n//i
;
s/^\s*KEY (.+).*(\(.*\)).*\n//i
;
if
(
$dq
&&
!
/^\s*(PRIMARY KEY|UNIQUE |KEY |CREATE TABLE |\);)/i
)
{
s/\s([A-Za-z_\d]+)\s/ $dq$+$dq /
;
}
}
####if($tabledef)###############################
if
(
$dq
&&
!
/^\s*(PRIMARY KEY|UNIQUE |KEY |CREATE TABLE|INSERT INTO|\);)/i
)
{
s/\s([A-Za-z_\d]+)\s/ $dq$+$dq /
;
}
}
# end of if($tabledef)
if
(
$dq
&&
!
s/INSERT INTO\s+?(.*?)\s+?/INSERT INTO $dq$1$dq /i
)
{
# Quote lowercase identifiers in double quotes
#while(!/^--/ && s/\s([A-Za-z_\d]+[a-z][A-Za-z_\d]*)\s/ $dq$+$dq /) {;}
}
s/INSERT INTO\s+?(.*?)\s+?/INSERT INTO $dq$1$dq /i
;
# if not defined -s command-line option (safe data conversion),
# attempting to convert timestamp data
if
(
!
$safe_data_conv
)
{
# Fix timestamps
s/'0000-00-00/'0001-01-01/g
;
# may work wrong !!!
s/([,(])00000000000000(?=[,)])/$1'00010101 000000'/g
;
s/([,(])(\d{8})(\d{6})(?=[,)])/$1'$2 $3'/g
;
s/([,(])(\d{4})(\d{2})(\d{2})(?=[,)])/$1'$2-$3-$4 00:00:00'/g
;
#<Hackzone> ---------------------------------------------------
#</Hackzone> --------------------------------------------------
s/'0000-00-00/'0001-01-01/g
;
# may corrupt data !!!
s/([,(])00000000000000(?=[,)])/$1'00010101 000000'/g
;
if
(
/[,(]\d{4}(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})[,)]/
&&
$
1
>=
0
&&
$
1
<=
12
&&
$
2
>=
0
&&
$
2
<=
31
&&
$
3
>=
0
&&
$
3
<=
23
&&
$
4
>=
0
&&
$
4
<=
59
&&
$
5
>=
0
&&
$
5
<=
59
)
{
s/([,(])(\d{8})(\d{6})(?=[,)])/$1'$2 $3'/g
;
}
if
(
/[,(]\d{4}(\d{2})(\d{2})[,)]/
&&
$
2
>=
0
&&
$
2
<=
12
&&
$
3
>=
0
&&
$
3
<=
31
)
{
s/([,(])(\d{4})(\d{2})(\d{2})(?=[,)])/$1'$2-$3-$4 00:00:00'/g
;
}
}
$dump
.=
$_
;
}
...
...
@@ -738,7 +762,7 @@ close(LIBTYPES);
open
(
MAKE
,"
>Makefile
");
print
MAKE
"
#
# My2Pg
\$
Revision: 1.1
1
$
\t
ranslated dump
# My2Pg
\$
Revision: 1.1
2
$
\t
ranslated dump
# Makefile
#
...
...
@@ -784,7 +808,7 @@ sub usage() {
print
<<EOF
my2pg - MySQL to PostgreSQL database dump converter
Copyright (c) 2000
Max Rudensky
<fonin\@ziet.zhitomir.ua>
Copyright (c) 2000
-2002 Max Rudensky
<fonin\@ziet.zhitomir.ua>
Copyright (c) 2000 Valentine Danilchuk <valdan\@ziet.zhitomir.ua>
This program is distributed in the hope that it will be useful,
...
...
@@ -793,12 +817,13 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
code source for license details.
SYNTAX:
my2pg [-hnd]
my2pg [-hnd
s
]
OPTIONS:
h - this help
n - convert *CHAR NOT NULL DEFAULT '' types to *CHAR NULL
d - double quotes around table and column names
d - double quotes around table and column names
s - do not attempt to convert data (timestamps at the moment)
EOF
;
}
...
...
@@ -810,7 +835,7 @@ my2pg - MySQL -> PostgreSQL dump conversion utility.
=head1 SYNTAX
mysqldump db | ./my2pg.pl [-n] > pgsqldump.sql
mysqldump db | ./my2pg.pl [-n
ds
] > pgsqldump.sql
vi libtypes.c
make
psql database < pgsqldump.txt
...
...
@@ -818,11 +843,11 @@ where
=over 4
=item
B
<pgsqldump.sql>
=item
F
<pgsqldump.sql>
- file suitable for loading into PostgreSQL.
=item
B
<libtypes.c>
=item
F
<libtypes.c>
- C source for emulated MySQL types (ENUM, SET) generated by B<my2pg>
...
...
@@ -835,7 +860,7 @@ B<my2pg> performs such conversions:
=over 4
=item Type conversion.
=item
*
Type conversion.
It tries to find proper Postgres
type for each column.
...
...
@@ -844,30 +869,30 @@ ENUM and SET types implemented via user types
(C source for such types can be found in
B<libtypes.c> file);
=item
Identifiers double-quotation
.
=item
* Encloses identifiers into double quotes
.
All column and table
names should be enclosed to double-quotes to prevent
interferension with reserved
words;
conflict with reserved SQL key
words;
=item Converting
=item
*
Converting
AUTO_INCREMENT fields to SERIAL. Actually, creating the sequence and
setting default value to nextval('seq'), well, you know :)
=item Converting
=item
*
Converting
KEY(field) to CREATE INDEX i_field on table (field);
=item The same
=item
*
The same
for UNIQUE keys;
=item Indices
=item
*
Indices
are creating AFTER rows insertion (to speed up the load);
=item Translates '#'
=item
*
Translates '#'
MySQL comments to ANSI SQL '--'
...
...
@@ -895,18 +920,23 @@ Add double quotes around table and column names
Show usage banner.
=item -s
Do not attempt to convert data. Currently my2pg only tries to convert
date and time data.
=back
=head1 SIDE EFFECTS
=over 4
=item creates
=item
*
creates
file B<libtypes.c> in current directory
overwriting existed file without any checks;
=item the same
=item
*
the same
for Makefile.
...
...
@@ -914,26 +944,42 @@ for Makefile.
=head1 BUGS
This program is still beta. Testers wanted.
Known bugs are:
=over 4
=item Poor doublequotation.
=item * Possible problems with the timestamp data.
PostgreSQL does not accept incorrect date/time values like B<2002-00-15>,
while MySQL does not care about that. Currently my2pg cannot handle this
issue. You should care yourself to convert such a data.
=item * Use -s option if your numeric data are broken during conversion.
My2pg attempts to convert MySQL timestamps of the form B<yyyymmdd> to
B<yyyy-mm-dd> and B<yyyymmddhhmmss> to B<yyyy-mm-dd hh:mm:ss>. It performs
some heuristic checks to ensure that the month,day,hour,minutes and seconds have
values from the correct range (0..12, 0..31, 0..23, 0..59, 0..59 respectively).
It is still possible that your numeric values that satisfy these conditions
will get broken.
=item * Possible problems with enclosing identifiers in double quotes.
All identifiers such as table and column names should be enclosed in double
quotes. Program can't handle upper-case identifiers,
like DBA. Lower-case identifiers are OK.
=item SET type emulation is not full. LIKE operation on
=item
*
SET type emulation is not full. LIKE operation on
SETs, raw integer input values should be implemented
=item B<Makefile> generated during output is
=item * B<Makefile>
generated during output is
platform-dependent and surely works only on
Linux/gcc (FreeBSD/gcc probably works as well - not tested)
=item Generated B<libtypes.c> contain line
=item
*
Generated B<libtypes.c> contain line
#include <postgres.h>
...
...
@@ -944,16 +990,25 @@ include path, you need to check it before compiling.
=head1 AUTHORS
B<(c) 2000 Maxim V. Rudensky (fonin@ziet.zhitomir.ua)>
B<(c) 2000 Valentine V. Danilchuk (valdan@ziet.zhitomir.ua)>
B<(c) 2000-2002 Maxim V. Rudensky (fonin@ziet.zhitomir.ua)> (developer, maintainer)
B<(c) 2000 Valentine V. Danilchuk (valdan@ziet.zhitomir.ua)> (original script)
=head1 CREDITS
Great thanks to all those people who provided feedback and make development
of this tool easier.
Jeff Waugh <jaw@ic.net>
Joakim Lemström <jocke@bytewize.com> || <buddyh19@hotmail.com>
Yunliang Yu <yu@math.duke.edu>
Brad Hilton <bhilton@vpop.net>
If you are not listed here please write to me.
=head1 LICENSE
B<BSD>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录