Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
085fa8ac
Commit
085fa8ac
authored
Apr 19, 2004
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update to my2pg 1.28, from:
http://www.omnistarinc.com/~fonin/downloads.php#my2pg
parent
52e4f27a
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
271 additions
and
216 deletions
+271
-216
contrib/mysql/my2pg.pl
contrib/mysql/my2pg.pl
+271
-216
No files found.
contrib/mysql/my2pg.pl
View file @
085fa8ac
...
@@ -35,17 +35,26 @@
...
@@ -35,17 +35,26 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
# SUCH DAMAGE.
#
#
# $My2pg: my2pg.pl,v 1.2
7
2001/12/06 19:32:20 fonin Exp $
# $My2pg: my2pg.pl,v 1.2
8
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 $
# $
Id: my2pg.pl,v 1.12 2004/04/19 23:11:49 momjian
Exp $
#
#
# $Log: my2pg.pl,v $
# $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
# Revision 1.28 2002/11/30 12:03:48 fonin
# Upgrade to my2pg 1.9
# 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
# Revision 1.27 2002/07/16 14:54:07 fonin
# Bugfix - didn't quote the fields inside PRIMARY KEY with -d option.
# Bugfix - didn't quote the fields inside PRIMARY KEY with -d option.
...
@@ -162,7 +171,7 @@ my $chareg=''; # CHAR conversion regexps
...
@@ -162,7 +171,7 @@ my $chareg=''; # CHAR conversion regexps
my
$dq
=
'';
# double quote
my
$dq
=
'';
# double quote
# parse command line
# parse command line
getopts
('
nhd
',
\%
opts
);
getopts
('
nhd
s
',
\%
opts
);
# output syntax
# output syntax
if
(
$opts
{
h
}
ne
'')
{
if
(
$opts
{
h
}
ne
'')
{
...
@@ -179,10 +188,17 @@ if($opts{d} ne '') {
...
@@ -179,10 +188,17 @@ if($opts{d} ne '') {
$dq
=
'
"
';
$dq
=
'
"
';
}
}
if
(
$opts
{
s} ne '') {
$safe_data_conv=1;
}
else {
$safe_data_conv=0;
}
$|
=
1
;
$|
=
1
;
print
("
------------------------------------------------------------------
");
print
("
------------------------------------------------------------------
");
print
("
\n
-- My2Pg 1.2
7
translated dump
");
print
("
\n
-- My2Pg 1.2
8
translated dump
");
print
("
\n
--
");
print
("
\n
--
");
print
("
\n
------------------------------------------------------------------
");
print
("
\n
------------------------------------------------------------------
");
...
@@ -213,86 +229,86 @@ print LIBTYPES "\n#define ADD_COMMA if(strcmp(result,\"\")!=0) strcat(result,\",
...
@@ -213,86 +229,86 @@ print LIBTYPES "\n#define ADD_COMMA if(strcmp(result,\"\")!=0) strcat(result,\",
# reading STDIN...
# reading STDIN...
my
$tabledef
=
0
;
# we are outside a table definition
my
$tabledef
=
0
;
# we are outside a table definition
while
(
<>
)
{
while
(
<>
)
{
if
(
!
$tabledef
&&
/^CREATE TABLE \S+/i
){
if
(
!
$tabledef
&&
/^CREATE TABLE \S+/i
){
$tabledef
=
1
;
$tabledef
=
1
;
}
elsif
(
$tabledef
&&
/^\) type=\w*;/i
){
# /^\w/i
}
elsif
(
$tabledef
&&
/^\) type=\w*;/i
){
# /^\w/i
$tabledef
=
0
;
$tabledef
=
0
;
}
}
# Comments start with -- in SQL
# Comments start with -- in SQL
if
(
/^#/
)
{
# !/insert into.*\(.*#.*\)/i, in mysqldump output
if
(
/^#/
)
{
# !/insert into.*\(.*#.*\)/i, in mysqldump output
s/#/--/
;
s/#/--/
;
}
}
if
(
$tabledef
){
##################################
if
(
$tabledef
)
{
# Convert numeric types
# Convert numeric types
s/tinyint\(\d+\)/INT2/i
;
s/tinyint\(\d+\)/INT2/i
;
s/smallint\(\d+\)/INT2/i
;
s/smallint\(\d+\)/INT2/i
;
s/mediumint\(\d+\)/INT4/i
;
s/mediumint\(\d+\)/INT4/i
;
s/bigint\(\d+\)/INT8/i
;
s/bigint\(\d+\)/INT8/i
;
s/int\(\d+\)/INT4/i
;
s/int\(\d+\)/INT4/i
;
s/float(\(\d+,\d*\))/DECIMAL$1/i
;
s/float(\(\d+,\d*\))/DECIMAL$1/i
;
s/double precision/FLOAT8 /i
;
s/double precision/FLOAT8 /i
;
s/([\W])double(\(\d+,\d*\))/$1DECIMAL$2/i
;
s/([\W])double(\(\d+,\d*\))/$1DECIMAL$2/i
;
s/([\W])double[\W]/$1FLOAT8 /i
;
s/([\W])double[\W]/$1FLOAT8 /i
;
s/([\W])real[\W]/$1FLOAT8 /i
;
s/([\W])real[\W]/$1FLOAT8 /i
;
s/([\W])real(\(\d+,\d*\))/$1DECIMAL$2/i
;
s/([\W])real(\(\d+,\d*\))/$1DECIMAL$2/i
;
# Convert string types
# Convert string types
s/\w*blob$chareg/text/i
;
s/\w*blob$chareg/text/i
;
s/mediumtext$chareg/text/i
;
s/mediumtext$chareg/text/i
;
s/tinytext$chareg/text/i
;
s/tinytext$chareg/text/i
;
s/\stext\s+not\s+null/ TEXT DEFAULT '' NOT NULL/i
;
s/\stext\s+not\s+null/ TEXT DEFAULT '' NOT NULL/i
;
s/(.*?char\(.*?\))$chareg/$1/i
;
s/(.*?char\(.*?\))$chareg/$1/i
;
# Old and New are reserved words in Postgres
# Old and New are reserved words in Postgres
s/^(\s+)Old /${1}MyOld /
;
s/^(\s+)Old /${1}MyOld /
;
s/^(\s+)New /${1}MyNew /
;
s/^(\s+)New /${1}MyNew /
;
# Convert DATE types
# Convert DATE types
s/datetime/TIMESTAMP/
;
s/datetime/TIMESTAMP/
;
s/timestamp\(\d+\)/TIMESTAMP/i
;
s/timestamp\(\d+\)/TIMESTAMP/i
;
s/ date / DATE /i
;
s/ date / DATE /i
;
s/,(\d{4})(\d{2})(\d{2}),/,'$1-$2-$3 00:00:00',/g
;
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
# small hack - convert "default" to uppercase, because below we
# enclose all lowercase words in double quotes
# enclose all lowercase words in double quotes
if
(
!
/^INSERT/
)
{
if
(
!
/^INSERT/
)
{
s/default/DEFAULT/
;
s/default/DEFAULT/
;
}
}
# Change all AUTO_INCREMENT fields to SERIAL ones with a pre-defined sequence
# Change all AUTO_INCREMENT fields to SERIAL ones with a pre-defined sequence
if
(
/([\w\d]+)\sint.*auto_increment/i
)
{
if
(
/([\w\d]+)\sint.*auto_increment/i
)
{
$tmpseq
=
new_name
("
$table_name
"
.
"
_
"
.
"
$+
"
.
"
_SEQ
",
28
);
$tmpseq
=
new_name
("
$table_name
"
.
"
_
"
.
"
$+
"
.
"
_SEQ
",
28
);
$seq
{
$table_name
}
=
$tmpseq
;
$seq
{
$table_name
}
=
$tmpseq
;
$primary
{
$table_name
}
=
$+
;
$primary
{
$table_name
}
=
$+
;
s/(int.*?) .*AUTO_INCREMENT/$1 DEFAULT nextval\('$tmpseq'\)/i
;
s/(int.*?) .*AUTO_INCREMENT/$1 DEFAULT nextval\('$tmpseq'\)/i
;
#s/(int.*?)DEFAULT\s*?'.*?'(.*?)AUTO_INCREMENT/$1$2DEFAULT nextval\('$tmpseq'\)/i;
}
}
# convert UNSIGNED to CHECK constraints
# convert UNSIGNED to CHECK constraints
if
(
/^\s+?([\w\d_]+).*?unsigned/i
)
{
if
(
/^\s+?([\w\d_]+).*?unsigned/i
)
{
$check
.=
"
,
\n
CHECK (
$dq
$1
$dq
>=0)
";
$check
.=
"
,
\n
CHECK (
$dq
$1
$dq
>=0)
";
}
}
s/unsigned//i
;
s/unsigned//i
;
# Limited ENUM support - little heuristic
# Limited ENUM support - little heuristic
s/enum\('N','Y'\)/BOOL/i
;
s/enum\('N','Y'\)/BOOL/i
;
s/enum\('Y','N'\)/BOOL/i
;
s/enum\('Y','N'\)/BOOL/i
;
# ENUM support
# ENUM support
if
(
/^\s+?([\w\d_]+).*?enum\((.*?)\)/i
)
{
if
(
/^\s+?([\w\d_]+).*?enum\((.*?)\)/i
)
{
my
$enumlist
=
$2
;
my
$enumlist
=
$2
;
my
@item
;
my
@item
;
$item
[
0
]
=
'';
$item
[
0
]
=
'';
while
(
$enumlist
=~
s/'([\d\w_]+)'//i
)
{
while
(
$enumlist
=~
s/'([\d\w_]+)'//i
)
{
$item
[
++
$#item
]
=
$1
;
$item
[
++
$#item
]
=
$1
;
}
}
# forming identifier name
# forming identifier name
$typename
=
new_name
('
enum_
'
.
$table_name
.
'
_
'
.
$item
[
1
],
28
);
$typename
=
new_name
('
enum_
'
.
$table_name
.
'
_
'
.
$item
[
1
],
28
);
# $typename=lc('enum_'.$table_name.'_'.$item[1]);
# creating input type function
# creating input type function
my
$func_in
=
"
my
$func_in
=
"
int2*
$typename
"
.
"
_in (char *str) {
int2*
$typename
"
.
"
_in (char *str) {
int2* result;
int2* result;
...
@@ -301,34 +317,34 @@ int2* $typename"."_in (char *str) {
...
@@ -301,34 +317,34 @@ int2* $typename"."_in (char *str) {
result=(int2*)palloc(sizeof(int2));
result=(int2*)palloc(sizeof(int2));
*result=-1;
";
*result=-1;
";
for
(
my
$i
=
0
;
$i
<=
$#item
;
$i
++
)
{
for
(
my
$i
=
0
;
$i
<=
$#item
;
$i
++
)
{
$func_in
.=
"
$func_in
.=
"
if(strcmp(str,
\"
$item
[
$i
]
\"
)==0) {
if(strcmp(str,
\"
$item
[
$i
]
\"
)==0) {
*result=
$i
;
*result=
$i
;
}
";
}
";
}
}
$func_in
.=
"
$func_in
.=
"
if(*result == -1) {
if(*result == -1) {
elog(ERROR,
\"
$typename
"
.
"
_in: incorrect input value
\"
);
elog(ERROR,
\"
$typename
"
.
"
_in: incorrect input value
\"
);
return NULL;
return NULL;
}
}
return (result);
return (result);
}
\n
";
}
\n
";
$types
.=
"
\n
---
";
$types
.=
"
\n
---
";
$types
.=
"
\n
--- Types for table
"
.
uc
(
$table_name
);
$types
.=
"
\n
--- Types for table
"
.
uc
(
$table_name
);
$types
.=
"
\n
---
\n
";
$types
.=
"
\n
---
\n
";
print
LIBTYPES
"
\n
/*
";
print
LIBTYPES
"
\n
/*
";
print
LIBTYPES
"
\n
* Types for table
"
.
uc
(
$table_name
);
print
LIBTYPES
"
\n
* Types for table
"
.
uc
(
$table_name
);
print
LIBTYPES
"
\n
*/
\n
";
print
LIBTYPES
"
\n
*/
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_in (opaque)
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_in (opaque)
RETURNS
$typename
RETURNS
$typename
AS '
$libtypename
'
AS '
$libtypename
'
LANGUAGE 'c'
LANGUAGE 'c'
WITH (ISCACHABLE);
\n
";
WITH (ISCACHABLE);
\n
";
# creating output function
# creating output function
my
$func_out
=
"
my
$func_out
=
"
char*
$typename
"
.
"
_out (int2 *outvalue) {
char*
$typename
"
.
"
_out (int2 *outvalue) {
char* result;
char* result;
...
@@ -337,13 +353,13 @@ char* $typename"."_out (int2 *outvalue) {
...
@@ -337,13 +353,13 @@ char* $typename"."_out (int2 *outvalue) {
result=(char*)palloc(10);
result=(char*)palloc(10);
switch (*outvalue) {
";
switch (*outvalue) {
";
for
(
my
$i
=
0
;
$i
<=
$#item
;
$i
++
)
{
for
(
my
$i
=
0
;
$i
<=
$#item
;
$i
++
)
{
$func_out
.=
"
$func_out
.=
"
case
$i
:
case
$i
:
strcpy(result,
\"
$item
[
$i
]
\"
);
strcpy(result,
\"
$item
[
$i
]
\"
);
break;
";
break;
";
}
}
$func_out
.=
"
$func_out
.=
"
default :
default :
elog(ERROR,
\"
$typename
"
.
"
_out: incorrect stored value
\"
);
elog(ERROR,
\"
$typename
"
.
"
_out: incorrect stored value
\"
);
return NULL;
return NULL;
...
@@ -351,7 +367,7 @@ char* $typename"."_out (int2 *outvalue) {
...
@@ -351,7 +367,7 @@ char* $typename"."_out (int2 *outvalue) {
}
}
return result;
return result;
}
\n
";
}
\n
";
$func_out
.=
"
\n
bool
$typename
"
.
"
_eq(int2* a, int2* b) {
$func_out
.=
"
\n
bool
$typename
"
.
"
_eq(int2* a, int2* b) {
return (*a==*b);
return (*a==*b);
}
}
...
@@ -375,19 +391,19 @@ bool $typename"."_ge(int2* a, int2* b) {
...
@@ -375,19 +391,19 @@ bool $typename"."_ge(int2* a, int2* b) {
return (*a>=*b);
return (*a>=*b);
}
\n
";
}
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_out (opaque)
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_out (opaque)
RETURNS opaque
RETURNS opaque
AS '
$libtypename
'
AS '
$libtypename
'
LANGUAGE 'c'
LANGUAGE 'c'
WITH (ISCACHABLE);
\n
";
WITH (ISCACHABLE);
\n
";
$types
.=
"
\n
CREATE TYPE
$typename
(
$types
.=
"
\n
CREATE TYPE
$typename
(
internallength = 2,
internallength = 2,
input =
$typename
\
_in,
input =
$typename
\
_in,
output =
$typename
\
_out
output =
$typename
\
_out
);
\n
";
);
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_eq (
$typename
,
$typename
)
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_eq (
$typename
,
$typename
)
RETURNS bool
RETURNS bool
AS '
$libtypename
'
AS '
$libtypename
'
LANGUAGE 'c';
LANGUAGE 'c';
...
@@ -460,32 +476,31 @@ CREATE OPERATOR <> (
...
@@ -460,32 +476,31 @@ CREATE OPERATOR <> (
procedure =
$typename
"
.
"
_ne
procedure =
$typename
"
.
"
_ne
);
\n
";
);
\n
";
print
LIBTYPES
$func_in
;
print
LIBTYPES
$func_in
;
print
LIBTYPES
$func_out
;
print
LIBTYPES
$func_out
;
s/enum\(.*?\)/$typename/i
;
s/enum\(.*?\)/$typename/i
;
}
}
# SET support
# SET support
if
(
/^\s+?([\w\d_]+).*?set\((.*?)\)/i
)
{
if
(
/^\s+?([\w\d_]+).*?set\((.*?)\)/i
)
{
my
$setlist
=
$2
;
my
$setlist
=
$2
;
my
@item
;
my
@item
;
$item
[
0
]
=
'';
$item
[
0
]
=
'';
my
$maxlen
=
0
;
# maximal string length
my
$maxlen
=
0
;
# maximal string length
while
(
$setlist
=~
s/'([\d\w_]+)'//i
)
{
while
(
$setlist
=~
s/'([\d\w_]+)'//i
)
{
$item
[
++
$#item
]
=
$1
;
$item
[
++
$#item
]
=
$1
;
$maxlen
+=
length
(
$item
[
$#item
])
+
1
;
$maxlen
+=
length
(
$item
[
$#item
])
+
1
;
}
}
$maxlen
+=
1
;
$maxlen
+=
1
;
my
$typesize
=
int
(
$#item
/
8
);
my
$typesize
=
int
(
$#item
/
8
);
if
(
$typesize
<
2
)
{
if
(
$typesize
<
2
)
{
$typesize
=
2
;
$typesize
=
2
;
}
}
$internalsize
=
$typesize
;
$internalsize
=
$typesize
;
$typesize
=
'
int
'
.
$typesize
;
$typesize
=
'
int
'
.
$typesize
;
# $typename=lc('set_'.$table_name.'_'.$item[1]);
$typename
=
new_name
('
set_
'
.
$table_name
.
'
_
'
.
$item
[
1
],
28
);
$typename
=
new_name
('
set_
'
.
$table_name
.
'
_
'
.
$item
[
1
],
28
);
# creating input type function
# creating input type function
my
$func_in
=
"
my
$func_in
=
"
$typesize
*
$typename
"
.
"
_in (char *str) {
$typesize
*
$typename
"
.
"
_in (char *str) {
$typesize
* result;
$typesize
* result;
char* token;
char* token;
...
@@ -498,14 +513,14 @@ $typesize* $typename"."_in (char *str) {
...
@@ -498,14 +513,14 @@ $typesize* $typename"."_in (char *str) {
if(strcmp(str,
\"\"
)==0)
if(strcmp(str,
\"\"
)==0)
return result;
return result;
for(token=strtok(str,
\"
,
\"
);token!=NULL;token=strtok(NULL,
\"
,
\"
)) {
";
for(token=strtok(str,
\"
,
\"
);token!=NULL;token=strtok(NULL,
\"
,
\"
)) {
";
for
(
my
$i
=
0
,
my
$j
=
1
;
$i
<=
$#item
;
$i
++
,
$j
*=
2
)
{
for
(
my
$i
=
0
,
my
$j
=
1
;
$i
<=
$#item
;
$i
++
,
$j
*=
2
)
{
$func_in
.=
"
$func_in
.=
"
if(strcmp(token,
\"
$item
[
$i
]
\"
)==0) {
if(strcmp(token,
\"
$item
[
$i
]
\"
)==0) {
*result|=
$j
;
*result|=
$j
;
continue;
continue;
}
";
}
";
}
}
$func_in
.=
"
$func_in
.=
"
}
}
if(*result == 0) {
if(*result == 0) {
...
@@ -515,20 +530,20 @@ $typesize* $typename"."_in (char *str) {
...
@@ -515,20 +530,20 @@ $typesize* $typename"."_in (char *str) {
return (result);
return (result);
}
\n
";
}
\n
";
$types
.=
"
\n
---
";
$types
.=
"
\n
---
";
$types
.=
"
\n
--- Types for table
"
.
uc
(
$table_name
);
$types
.=
"
\n
--- Types for table
"
.
uc
(
$table_name
);
$types
.=
"
\n
---
\n
";
$types
.=
"
\n
---
\n
";
print
LIBTYPES
"
\n
/*
";
print
LIBTYPES
"
\n
/*
";
print
LIBTYPES
"
\n
* Types for table
"
.
uc
(
$table_name
);
print
LIBTYPES
"
\n
* Types for table
"
.
uc
(
$table_name
);
print
LIBTYPES
"
\n
*/
\n
";
print
LIBTYPES
"
\n
*/
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_in (opaque)
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_in (opaque)
RETURNS
$typename
RETURNS
$typename
AS '
$libtypename
'
AS '
$libtypename
'
LANGUAGE 'c';
\n
";
LANGUAGE 'c';
\n
";
# creating output function
# creating output function
my
$func_out
=
"
my
$func_out
=
"
char*
$typename
"
.
"
_out (
$typesize
*outvalue) {
char*
$typename
"
.
"
_out (
$typesize
*outvalue) {
char* result;
char* result;
int i;
int i;
...
@@ -540,16 +555,16 @@ char* $typename"."_out ($typesize *outvalue) {
...
@@ -540,16 +555,16 @@ char* $typename"."_out ($typesize *outvalue) {
strcpy(result,
\"\"
);
strcpy(result,
\"\"
);
for(i=1;i<=2 << (sizeof(int2)*8);i*=2) {
for(i=1;i<=2 << (sizeof(int2)*8);i*=2) {
switch (*outvalue & i) {
";
switch (*outvalue & i) {
";
for
(
my
$i
=
0
,
$j
=
1
;
$i
<=
$#item
;
$i
++
,
$j
*=
2
)
{
for
(
my
$i
=
0
,
$j
=
1
;
$i
<=
$#item
;
$i
++
,
$j
*=
2
)
{
$func_out
.=
"
$func_out
.=
"
case
$j
:
";
case
$j
:
";
if
(
$item
[
$i
]
ne
'')
{
if
(
$item
[
$i
]
ne
'')
{
$func_out
.=
"
ADD_COMMA;
";
$func_out
.=
"
ADD_COMMA;
";
}
}
$func_out
.=
"
strcat(result,
\"
$item
[
$i
]
\"
);
$func_out
.=
"
strcat(result,
\"
$item
[
$i
]
\"
);
break;
";
break;
";
}
}
$func_out
.=
"
$func_out
.=
"
default :
default :
break;
break;
}
}
...
@@ -557,7 +572,7 @@ char* $typename"."_out ($typesize *outvalue) {
...
@@ -557,7 +572,7 @@ char* $typename"."_out ($typesize *outvalue) {
return result;
return result;
}
\n
";
}
\n
";
$func_out
.=
"
\n
bool
$typename
"
.
"
_eq(
$typesize
* a,
$typesize
* b) {
$func_out
.=
"
\n
bool
$typename
"
.
"
_eq(
$typesize
* a,
$typesize
* b) {
return (*a==*b);
return (*a==*b);
}
}
...
@@ -574,18 +589,18 @@ $typesize find_in_set($typesize *a, $typesize *b) {
...
@@ -574,18 +589,18 @@ $typesize find_in_set($typesize *a, $typesize *b) {
\n
";
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_out (opaque)
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_out (opaque)
RETURNS opaque
RETURNS opaque
AS '
$libtypename
'
AS '
$libtypename
'
LANGUAGE 'c';
\n
";
LANGUAGE 'c';
\n
";
$types
.=
"
\n
CREATE TYPE
$typename
(
$types
.=
"
\n
CREATE TYPE
$typename
(
internallength =
$internalsize
,
internallength =
$internalsize
,
input =
$typename
\
_in,
input =
$typename
\
_in,
output =
$typename
\
_out
output =
$typename
\
_out
);
\n
";
);
\n
";
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_eq (
$typename
,
$typename
)
$types
.=
"
\n
CREATE FUNCTION
$typename
"
.
"
_eq (
$typename
,
$typename
)
RETURNS bool
RETURNS bool
AS '
$libtypename
'
AS '
$libtypename
'
LANGUAGE 'c';
LANGUAGE 'c';
...
@@ -612,10 +627,10 @@ CREATE OPERATOR <> (
...
@@ -612,10 +627,10 @@ CREATE OPERATOR <> (
\n
";
\n
";
print
LIBTYPES
$func_in
;
print
LIBTYPES
$func_in
;
print
LIBTYPES
$func_out
;
print
LIBTYPES
$func_out
;
s/set\(.*?\)/$typename/i
;
s/set\(.*?\)/$typename/i
;
}
}
# Change multy-field keys to multi-field indices
# Change multy-field keys to multi-field indices
# MySQL Dump usually ends the CREATE TABLE statement like this:
# MySQL Dump usually ends the CREATE TABLE statement like this:
...
@@ -632,71 +647,80 @@ CREATE OPERATOR <> (
...
@@ -632,71 +647,80 @@ CREATE OPERATOR <> (
# );
# );
# CREATE INDEX offer_id ON bids (offer_id,user_id,the_time);
# CREATE INDEX offer_id ON bids (offer_id,user_id,the_time);
# CREATE INDEX bid_value ON bids (bid_value);
# CREATE INDEX bid_value ON bids (bid_value);
if
(
s/CREATE TABLE (.*) /CREATE TABLE $dq$1$dq /i
)
{
if
(
s/CREATE TABLE (.*) /CREATE TABLE $dq$1$dq /i
)
{
if
(
$oldtable
ne
$table_name
)
{
if
(
$oldtable
ne
$table_name
)
{
$oldtable
=
$table_name
;
$oldtable
=
$table_name
;
$j
=-
1
;
$j
=-
1
;
$check
=
'';
$check
=
'';
if
(
$seq
{
$table_name
}
ne
'')
{
if
(
$seq
{
$table_name
}
ne
'')
{
print
"
\n\n
--
";
print
"
\n\n
--
";
print
"
\n
-- Sequences for table
"
.
uc
(
$table_name
);
print
"
\n
-- Sequences for table
"
.
uc
(
$table_name
);
print
"
\n
--
\n
";
print
"
\n
--
\n
";
print
"
\n
CREATE SEQUENCE
"
.
$seq
{
$table_name
}
.
"
;
\n\n
";
print
"
\n
CREATE SEQUENCE
"
.
$seq
{
$table_name
}
.
"
;
\n\n
";
}
}
print
$types
;
print
$types
;
$types
=
'';
$types
=
'';
$dump
=~
s/,\n\).*;/\n\);/gmi
;
$dump
=~
s/,\n\).*;/\n\);/gmi
;
# removing table options after closing bracket:
# removing table options after closing bracket:
# ) TYPE=ISAM PACK_KEYS=1;
# ) TYPE=ISAM PACK_KEYS=1;
$dump
=~
s/\n\).*/\n\);/gmi
;
$dump
=~
s/\n\).*/\n\);/gmi
;
print
$dump
;
print
$dump
;
$dump
=
'';
$dump
=
'';
}
}
$table_name
=
$1
;
$table_name
=
$1
;
}
}
# output CHECK constraints instead UNSIGNED modifiers
# output CHECK constraints instead UNSIGNED modifiers
if
(
/PRIMARY KEY\s+\((.*)\)/i
)
{
if
(
/PRIMARY KEY\s+\((.*)\)/i
)
{
my
$tmpfld
=
$1
;
my
$tmpfld
=
$1
;
$tmpfld
=~
s/,/","/g
if
$dq
;
$tmpfld
=~
s/,/","/g
if
$dq
;
$tmpfld
=~
s/ //g
;
$tmpfld
=~
s/ //g
;
s/PRIMARY KEY\s+(\(.*\))/PRIMARY KEY \($dq$tmpfld$dq\)/i
;
s/PRIMARY KEY\s+(\(.*\))/PRIMARY KEY \($dq$tmpfld$dq\)/i
;
s/(PRIMARY KEY \(.*\)).*/$1$check\n/i
;
s/(PRIMARY KEY \(.*\)).*/$1$check\n/i
;
}
}
if
(
/^\s*KEY ([\w\d_]+)\s*\((.*)\).*/i
)
{
if
(
/^\s*KEY ([\w\d_]+)\s*\((.*)\).*/i
)
{
my
$tmpfld
=
$2
;
my
$ky
=
$1
;
my
$tmpfld
=
$2
;
my
$ky
=
$1
;
$tmpfld
=~
s/\s*,\s*/","/g
if
$dq
;
$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
);
";
$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
;
if
(
/^\s*UNIQUE.*?([\w\d_]+)\s*\((.*)\).*/i
)
{
$tmpfld
=~
s/,/","/g
if
$dq
;
my
$tmpfld
=
$2
;
my
$ky
=
$1
;
$index
{
$table_name
}[
++
$j
]
=
"
CREATE UNIQUE INDEX
${ky}
_
$table_name
\
_index ON
$dq$table_name$dq
(
$dq$tmpfld$dq
);
";
$tmpfld
=~
s/,/","/g
if
$dq
;
}
$tmpfld
=~
s/(\(\d+\))//g
;
s/^\s*UNIQUE (.+).*(\(.*\)).*\n//i
;
$index
{
$table_name
}[
++
$j
]
=
"
CREATE UNIQUE INDEX
${ky}
_
$table_name
\
_index ON
$dq$table_name$dq
(
$dq$tmpfld$dq
);
";
s/^\s*KEY (.+).*(\(.*\)).*\n//i
;
}
s/^\s*UNIQUE (.+).*(\(.*\)).*\n//i
;
s/^\s*KEY (.+).*(\(.*\)).*\n//i
;
if
(
$dq
&&
!
/^\s*(PRIMARY KEY|UNIQUE |KEY |CREATE TABLE |\);)/i
)
{
if
(
$dq
&&
!
/^\s*(PRIMARY KEY|UNIQUE |KEY |CREATE TABLE|INSERT INTO|\);)/i
)
{
s/\s([A-Za-z_\d]+)\s/ $dq$+$dq /
;
s/\s([A-Za-z_\d]+)\s/ $dq$+$dq /
;
}
}
}
####if($tabledef)###############################
}
# end of if($tabledef)
if
(
$dq
&&
!
s/INSERT INTO\s+?(.*?)\s+?/INSERT INTO $dq$1$dq /i
)
{
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 /) {;}
}
# if not defined -s command-line option (safe data conversion),
# attempting to convert timestamp data
if
(
!
$safe_data_conv
)
{
# Fix timestamps
# Fix timestamps
s/'0000-00-00/'0001-01-01/g
;
s/'0000-00-00/'0001-01-01/g
;
# may work wrong !!!
# may corrupt data !!!
s/([,(])00000000000000(?=[,)])/$1'00010101 000000'/g
;
s/([,(])00000000000000(?=[,)])/$1'00010101 000000'/g
;
s/([,(])(\d{8})(\d{6})(?=[,)])/$1'$2 $3'/g
;
if
(
/[,(]\d{4}(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})[,)]/
&&
s/([,(])(\d{4})(\d{2})(\d{2})(?=[,)])/$1'$2-$3-$4 00:00:00'/g
;
$1
>=
0
&&
$1
<=
12
&&
$2
>=
0
&&
$2
<=
31
&&
$3
>=
0
&&
$3
<=
23
&&
#<Hackzone> ---------------------------------------------------
$4
>=
0
&&
$4
<=
59
&&
$5
>=
0
&&
$5
<=
59
)
{
#</Hackzone> --------------------------------------------------
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
.=
$_
;
$dump
.=
$_
;
}
}
...
@@ -738,7 +762,7 @@ close(LIBTYPES);
...
@@ -738,7 +762,7 @@ close(LIBTYPES);
open
(
MAKE
,"
>Makefile
");
open
(
MAKE
,"
>Makefile
");
print
MAKE
"
#
print
MAKE
"
#
# My2Pg
\
$Revision
: 1.1
1
$
\t
ranslated dump
# My2Pg
\
$Revision
: 1.1
2
$
\t
ranslated dump
# Makefile
# Makefile
#
#
...
@@ -784,7 +808,7 @@ sub usage() {
...
@@ -784,7 +808,7 @@ sub usage() {
print
<<EOF
print
<<EOF
my2pg - MySQL to PostgreSQL database dump converter
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>
Copyright (c) 2000 Valentine Danilchuk <valdan\@ziet.zhitomir.ua>
This program is distributed in the hope that it will be useful,
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
...
@@ -793,12 +817,13 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
code source for license details.
code source for license details.
SYNTAX:
SYNTAX:
my2pg [-hnd]
my2pg [-hnd
s
]
OPTIONS:
OPTIONS:
h - this help
h - this help
n - convert *CHAR NOT NULL DEFAULT '' types to *CHAR NULL
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
EOF
;
;
}
}
...
@@ -810,7 +835,7 @@ my2pg - MySQL -> PostgreSQL dump conversion utility.
...
@@ -810,7 +835,7 @@ my2pg - MySQL -> PostgreSQL dump conversion utility.
=head1 SYNTAX
=head1 SYNTAX
mysqldump db | ./my2pg.pl [-n] > pgsqldump.sql
mysqldump db | ./my2pg.pl [-n
ds
] > pgsqldump.sql
vi libtypes.c
vi libtypes.c
make
make
psql database < pgsqldump.txt
psql database < pgsqldump.txt
...
@@ -818,11 +843,11 @@ where
...
@@ -818,11 +843,11 @@ where
=over 4
=over 4
=item
B
<pgsqldump.sql>
=item
F
<pgsqldump.sql>
- file suitable for loading into PostgreSQL.
- 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>
- C source for emulated MySQL types (ENUM, SET) generated by B<my2pg>
...
@@ -835,7 +860,7 @@ B<my2pg> performs such conversions:
...
@@ -835,7 +860,7 @@ B<my2pg> performs such conversions:
=over 4
=over 4
=item Type conversion.
=item
*
Type conversion.
It tries to find proper Postgres
It tries to find proper Postgres
type for each column.
type for each column.
...
@@ -844,30 +869,30 @@ ENUM and SET types implemented via user types
...
@@ -844,30 +869,30 @@ ENUM and SET types implemented via user types
(C source for such types can be found in
(C source for such types can be found in
B<libtypes.c> file);
B<libtypes.c> file);
=item
Identifiers double-quotation
.
=item
* Encloses identifiers into double quotes
.
All column and table
All column and table
names should be enclosed to double-quotes to prevent
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
AUTO_INCREMENT fields to SERIAL. Actually, creating the sequence and
setting default value to nextval('seq'), well, you know :)
setting default value to nextval('seq'), well, you know :)
=item Converting
=item
*
Converting
KEY(field) to CREATE INDEX i_field on table (field);
KEY(field) to CREATE INDEX i_field on table (field);
=item The same
=item
*
The same
for UNIQUE keys;
for UNIQUE keys;
=item Indices
=item
*
Indices
are creating AFTER rows insertion (to speed up the load);
are creating AFTER rows insertion (to speed up the load);
=item Translates '#'
=item
*
Translates '#'
MySQL comments to ANSI SQL '--'
MySQL comments to ANSI SQL '--'
...
@@ -895,18 +920,23 @@ Add double quotes around table and column names
...
@@ -895,18 +920,23 @@ Add double quotes around table and column names
Show usage banner.
Show usage banner.
=item -s
Do not attempt to convert data. Currently my2pg only tries to convert
date and time data.
=back
=back
=head1 SIDE EFFECTS
=head1 SIDE EFFECTS
=over 4
=over 4
=item creates
=item
*
creates
file B<libtypes.c> in current directory
file B<libtypes.c> in current directory
overwriting existed file without any checks;
overwriting existed file without any checks;
=item the same
=item
*
the same
for Makefile.
for Makefile.
...
@@ -914,26 +944,42 @@ for Makefile.
...
@@ -914,26 +944,42 @@ for Makefile.
=head1 BUGS
=head1 BUGS
This program is still beta. Testers wanted.
Known bugs are:
Known bugs are:
=over 4
=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
All identifiers such as table and column names should be enclosed in double
quotes. Program can't handle upper-case identifiers,
quotes. Program can't handle upper-case identifiers,
like DBA. Lower-case identifiers are OK.
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
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
platform-dependent and surely works only on
Linux/gcc (FreeBSD/gcc probably works as well - not tested)
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>
#include <postgres.h>
...
@@ -944,16 +990,25 @@ include path, you need to check it before compiling.
...
@@ -944,16 +990,25 @@ include path, you need to check it before compiling.
=head1 AUTHORS
=head1 AUTHORS
B<(c) 2000 Maxim V. Rudensky (fonin@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)>
B<(c) 2000 Valentine V. Danilchuk (valdan@ziet.zhitomir.ua)> (original script)
=head1 CREDITS
=head1 CREDITS
Great thanks to all those people who provided feedback and make development
of this tool easier.
Jeff Waugh <jaw@ic.net>
Jeff Waugh <jaw@ic.net>
Joakim Lemström <jocke@bytewize.com> || <buddyh19@hotmail.com>
Joakim Lemström <jocke@bytewize.com> || <buddyh19@hotmail.com>
Yunliang Yu <yu@math.duke.edu>
Yunliang Yu <yu@math.duke.edu>
Brad Hilton <bhilton@vpop.net>
Brad Hilton <bhilton@vpop.net>
If you are not listed here please write to me.
=head1 LICENSE
=head1 LICENSE
B<BSD>
B<BSD>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment