3
# Copyright (C) 2000-2006 MySQL AB
5
# This library is free software; you can redistribute it and/or
6
# modify it under the terms of the GNU Library General Public
7
# License as published by the Free Software Foundation; version 2
10
# This library is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
# Library General Public License for more details.
15
# You should have received a copy of the GNU Library General Public
16
# License along with this library; if not, write to the Free
17
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20
# The configuration file for the DBI/DBD tests on different databases ....
21
# You will need the DBD module for the database you are running.
22
# Monty made this bench script and I (Luuk de Boer) rewrote it to DBI/DBD.
23
# Monty rewrote this again to use packages.
25
# Each database has a different package that has 3 functions:
26
# new Creates a object with some standard slot
27
# version Version number of the server
28
# create Generates commands to create a table
32
# First some global functions that help use the packages:
37
my ($name,$host,$database,$odbc,$machine,$socket,$connect_options)=@_;
39
if ($name =~ /mysql/i)
40
{ $server=new db_MySQL($host, $database, $machine, $socket,$connect_options); }
41
elsif ($name =~ /drizzle/i)
42
{ $server=new db_Drizzle($host, $database, $machine, $connect_options); }
43
elsif ($name =~ /pg/i)
44
{ $server= new db_Pg($host,$database); }
45
elsif ($name =~ /msql/i)
46
{ $server= new db_mSQL($host,$database); }
47
elsif ($name =~ /solid/i)
48
{ $server= new db_Solid($host,$database); }
49
elsif ($name =~ /Empress/i)
50
{ $server= new db_Empress($host,$database); }
51
elsif ($name =~ /FrontBase/i)
52
{ $server= new db_FrontBase($host,$database); }
53
elsif ($name =~ /Oracle/i)
54
{ $server= new db_Oracle($host,$database); }
55
elsif ($name =~ /Access/i)
56
{ $server= new db_access($host,$database); }
57
elsif ($name =~ /Informix/i)
58
{ $server= new db_Informix($host,$database); }
59
elsif ($name =~ /ms-sql/i)
60
{ $server= new db_ms_sql($host,$database); }
61
elsif ($name =~ /sybase/i)
62
{ $server= new db_sybase($host,$database); }
63
elsif ($name =~ /Adabas/i) # Adabas has two drivers
65
$server= new db_Adabas($host,$database);
66
if ($name =~ /AdabasD/i)
68
$server->{'data_source'} =~ s/:Adabas:/:AdabasD:/;
71
elsif ($name =~ /DB2/i)
72
{ $server= new db_db2($host,$database); }
73
elsif ($name =~ /Mimer/i)
74
{ $server= new db_Mimer($host,$database); }
75
elsif ($name =~ /Sapdb/i)
76
{ $server= new db_sapdb($host,$database); }
77
elsif ($name =~ /interBase/i)
78
{ $server= new db_interbase($host,$database); }
81
die "Unknown sql server name used: $name\nUse one of: Access, Adabas, AdabasD, Empress, FrontBase, Oracle, Informix, InterBase, DB2, mSQL, Mimer, MS-SQL, MySQL, Pg, Solid, SAPDB or Sybase.\nIf the connection is done trough ODBC the name must end with _ODBC\n";
83
if ($name =~ /_ODBC$/i || defined($odbc) && $odbc)
85
if (! ($server->{'data_source'} =~ /^([^:]*):([^:]+):([^:]*)/ ))
87
die "Can't find databasename in data_source: '" .
88
$server->{'data_source'}. "'\n";
91
$server->{'data_source'} = "$1:ODBC:$3";
93
$server->{'data_source'} = "$1:ODBC:$database";
101
return ["Access", "Adabas", "DB2", "Drizzle", "Empress", "FrontBase", "Oracle",
102
"Informix", "InterBase", "Mimer", "mSQL", "MS-SQL", "MySQL", "Pg","SAPDB",
107
# Create a filename part for the machine that can be used for log file.
113
return $opt_machine if (length($opt_machine)); # Specified by user
115
$orig=$name=machine();
116
$name="win9$1" if ($orig =~ /win.*9(\d)/i);
117
$name="NT_$1" if ($orig =~ /Windows NT.*(\d+\.\d+)/i);
118
$name="win2k" if ($orig =~ /Windows 2000/i);
119
$name =~ s/\s+/_/g; # Make the filenames easier to parse
127
my @name = POSIX::uname();
128
my $name= $name[0] . " " . $name[2] . " " . $name[4];
132
#############################################################################
133
# First the configuration for MySQL off course :-)
134
#############################################################################
140
my ($type,$host,$database,$machine,$socket,$connect_options)= @_;
145
$self->{'cmp_name'} = "mysql";
146
$self->{'data_source'} = "DBI:mysql:database=$database;host=$host";
147
$self->{'data_source'} .= ";mysql_socket=$socket" if($socket);
148
$self->{'data_source'} .= ";$connect_options" if($connect_options);
149
$self->{'limits'} = \%limits;
150
$self->{'blob'} = "blob";
151
$self->{'text'} = "text";
152
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
153
$self->{'vacuum'} = 1; # When using with --fast
154
$self->{'drop_attr'} = "";
155
$self->{'transactions'} = 0; # Transactions disabled by default
157
$limits{'NEG'} = 1; # Supports -id
158
$limits{'alter_add_multi_col'}= 1; #Have ALTER TABLE t add a int,add b int;
159
$limits{'alter_table'} = 1; # Have ALTER TABLE
160
$limits{'alter_table_dropcol'}= 1; # Have ALTER TABLE DROP column
161
$limits{'column_alias'} = 1; # Alias for fields in select statement.
162
$limits{'func_extra_%'} = 1; # Has % as alias for mod()
163
$limits{'func_extra_if'} = 1; # Have function if.
164
$limits{'func_extra_in_num'} = 1; # Has function in
165
$limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function
166
$limits{'func_odbc_mod'} = 1; # Have function mod.
167
$limits{'functions'} = 1; # Has simple functions (+/-)
168
$limits{'group_by_position'} = 1; # Can use 'GROUP BY 1'
169
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
170
$limits{'group_func_extra_std'} = 1; # Have group function std().
171
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
172
$limits{'group_functions'} = 1; # Have group functions
173
$limits{'having_with_alias'} = 1; # Can use aliases in HAVING
174
$limits{'having_with_group'} = 1; # Can use group functions in HAVING
175
$limits{'insert_multi_value'} = 1; # Have INSERT ... values (1,2),(3,4)
176
$limits{'insert_select'} = 1;
177
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
178
$limits{'left_outer_join'} = 1; # Supports left outer joins
179
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
180
$limits{'limit'} = 1; # supports the limit attribute
181
$limits{'truncate_table'} = 1;
182
$limits{'load_data_infile'} = 1; # Has load data infile
183
$limits{'lock_tables'} = 1; # Has lock tables
184
$limits{'max_column_name'} = 64; # max table and column name
185
$limits{'max_columns'} = 2000; # Max number of columns in table
186
$limits{'max_conditions'} = 9999; # (Actually not a limit)
187
$limits{'max_index'} = 16; # Max number of keys
188
$limits{'max_index_parts'} = 16; # Max segments/key
189
$limits{'max_tables'} = (($machine || '') =~ "^win") ? 5000 : 65000;
190
$limits{'max_text_size'} = 1000000; # Good enough for tests
191
$limits{'multi_drop'} = 1; # Drop table can take many tables
192
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
193
$limits{'order_by_unused'} = 1;
194
$limits{'query_size'} = 1000000; # Max size with default buffers.
195
$limits{'select_without_from'}= 1; # Can do 'select 1';
196
$limits{'subqueries'} = 1; # Doesn't support sub-queries.
197
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
198
$limits{'unique_index'} = 1; # Unique index works or not
199
$limits{'working_all_fields'} = 1;
200
$limits{'working_blobs'} = 1; # If big varchar/blobs works
201
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
203
# Some fixes that depends on the environment
204
if (defined($main::opt_create_options) &&
205
$main::opt_create_options =~ /engine=heap/i)
207
$limits{'working_blobs'} = 0; # HEAP tables can't handle BLOB's
209
if (defined($main::opt_create_options) &&
210
$main::opt_create_options =~ /engine=innodb/i)
212
$self->{'transactions'} = 1; # Transactions enabled
214
if (defined($main::opt_create_options) &&
215
$main::opt_create_options =~ /engine=ndb/i)
217
$self->{'transactions'} = 1; # Transactions enabled
218
$limits{'max_columns'} = 90; # Max number of columns in table
219
$limits{'max_tables'} = 32; # No comments
221
if (defined($main::opt_create_options) &&
222
$main::opt_create_options =~ /engine=bdb/i)
224
$self->{'transactions'} = 1; # Transactions enabled
226
if (defined($main::opt_create_options) &&
227
$main::opt_create_options =~ /engine=gemini/i)
229
$limits{'working_blobs'} = 0; # Blobs not implemented yet
230
$limits{'max_tables'} = 500;
231
$self->{'transactions'} = 1; # Transactions enabled
237
# Get the version number of the database
243
my ($dbh,$sth,$version,@row);
245
$dbh=$self->connect();
246
$sth = $dbh->prepare("select VERSION()") or die $DBI::errstr;
247
$version="MySQL 3.20.?";
248
if ($sth->execute && (@row = $sth->fetchrow_array))
250
$row[0] =~ s/-/ /g; # To get better tables with long names
251
$version="MySQL $row[0]";
255
$sth = $dbh->prepare("show status like 'ssl_version'") or die $DBI::errstr;
256
if ($sth->execute && (@row = $sth->fetchrow_array) && $row[1])
258
$version .= "/$row[1]";
262
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
267
# Connection with optional disabling of logging
274
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
275
$main::opt_password,{ PrintError => 0}) ||
276
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
278
$dbh->do("SET OPTION LOG_OFF=1,UPDATE_LOG=0");
283
# Returns a list of statements to create a table
284
# The field types are in ANSI SQL format.
286
# If one uses $main::opt_fast then one is allowed to use
287
# non standard types to get better speed.
292
my($self,$table_name,$fields,$index,$options) = @_;
295
$query="create table $table_name (";
296
foreach $field (@$fields)
298
# $field =~ s/ decimal/ double(10,2)/i;
299
$field =~ s/ big_decimal/ double(10,2)/i;
300
$query.= $field . ',';
302
foreach $index (@$index)
304
$query.= $index . ',';
306
substr($query,-1)=")"; # Remove last ',';
307
$query.=" $options" if (defined($options));
308
$query.=" $main::opt_create_options" if (defined($main::opt_create_options));
309
push(@queries,$query);
314
my ($self,$dbname, $file, $dbh) = @_;
317
$file =~ s|\\|/|g; # Change Win32 names to Unix syntax
318
$command = "load data infile '$file' into table $dbname columns optionally enclosed by '\\'' terminated by ','";
319
# print "$command\n";
320
$sth = $dbh->do($command) or die $DBI::errstr;
321
return $sth; # Contains number of rows
325
# Do any conversions to the ANSI SQL query so that the database can handle it
334
my ($self,$table,$index) = @_;
335
return "DROP INDEX $index ON $table";
339
# Abort if the server has crashed
341
# 1 question should be retried
344
sub abort_if_fatal_error
350
# This should return 1 if we to do disconnect / connect when doing
354
sub small_rollback_segment
360
# reconnect on errors (needed mainly be crash-me)
363
sub reconnect_on_errors
370
my ($self,$cmd) = @_;
375
# Optimize tables for better performance
380
my ($self,$full_vacuum,$dbh_ref,@tables)=@_;
381
my ($loop_time,$end_time,$dbh);
385
$loop_time=new Benchmark;
386
$dbh->do("OPTIMIZE TABLE " . join(',',@tables)) || die "Got error: $DBI::errstr when executing 'OPTIMIZE TABLE'\n";
387
$end_time=new Benchmark;
388
print "Time for book-keeping (1): " .
389
Benchmark::timestr(Benchmark::timediff($end_time, $loop_time),"all") . "\n\n";
398
my ($type,$host,$database,$machine,$connect_options)= @_;
403
$self->{'cmp_name'} = "drizzle";
404
$self->{'data_source_no_schema'} = "DBI:drizzle:database=information_schema;host=$host";
405
$self->{'data_source_no_schema'} .= ";$connect_options" if($connect_options);
406
$self->{'data_source'} = "DBI:drizzle:database=$database;host=$host";
407
$self->{'data_source'} .= ";$connect_options" if($connect_options);
408
$self->{'limits'} = \%limits;
409
$self->{'blob'} = "blob";
410
$self->{'text'} = "text";
411
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
412
$self->{'vacuum'} = 1; # When using with --fast
413
$self->{'drop_attr'} = "";
414
$self->{'transactions'} = 1; # Transactions enabled by default
416
$limits{'NEG'} = 1; # Supports -id
417
$limits{'alter_add_multi_col'}= 1; #Have ALTER TABLE t add a int,add b int;
418
$limits{'alter_table'} = 1; # Have ALTER TABLE
419
$limits{'alter_table_dropcol'}= 1; # Have ALTER TABLE DROP column
420
$limits{'column_alias'} = 1; # Alias for fields in select statement.
421
$limits{'func_extra_%'} = 1; # Has % as alias for mod()
422
$limits{'func_extra_if'} = 1; # Have function if.
423
$limits{'func_extra_in_num'} = 1; # Has function in
424
$limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function
425
$limits{'func_odbc_mod'} = 1; # Have function mod.
426
$limits{'functions'} = 1; # Has simple functions (+/-)
427
$limits{'group_by_position'} = 1; # Can use 'GROUP BY 1'
428
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
429
$limits{'group_func_extra_std'} = 1; # Have group function std().
430
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
431
$limits{'group_functions'} = 1; # Have group functions
432
$limits{'having_with_alias'} = 1; # Can use aliases in HAVING
433
$limits{'having_with_group'} = 1; # Can use group functions in HAVING
434
$limits{'insert_multi_value'} = 1; # Have INSERT ... values (1,2),(3,4)
435
$limits{'insert_select'} = 1;
436
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
437
$limits{'left_outer_join'} = 1; # Supports left outer joins
438
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
439
$limits{'limit'} = 1; # supports the limit attribute
440
$limits{'truncate_table'} = 1;
441
$limits{'load_data_infile'} = 1; # Has load data infile
442
$limits{'lock_tables'} = 1; # Has lock tables
443
$limits{'max_column_name'} = 64; # max table and column name
444
$limits{'max_columns'} = 2000; # Max number of columns in table
445
$limits{'max_conditions'} = 9999; # (Actually not a limit)
446
$limits{'max_index'} = 16; # Max number of keys
447
$limits{'max_index_parts'} = 16; # Max segments/key
448
$limits{'max_tables'} = (($machine || '') =~ "^win") ? 5000 : 65000;
449
$limits{'max_text_size'} = 1000000; # Good enough for tests
450
$limits{'multi_drop'} = 1; # Drop table can take many tables
451
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
452
$limits{'order_by_unused'} = 1;
453
$limits{'query_size'} = 65535; # Max size with default buffers.
454
$limits{'select_without_from'}= 1; # Can do 'select 1';
455
$limits{'subqueries'} = 1; # Doesn't support sub-queries.
456
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
457
$limits{'unique_index'} = 1; # Unique index works or not
458
$limits{'working_all_fields'} = 1;
459
$limits{'working_blobs'} = 1; # If big varchar/blobs works
460
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
462
# Some fixes that depends on the environment
463
if (defined($main::opt_create_options) &&
464
$main::opt_create_options =~ /engine=heap/i)
466
$limits{'working_blobs'} = 0; # HEAP tables can't handle BLOB's
468
if (defined($main::opt_create_options) &&
469
$main::opt_create_options =~ /engine=innodb/i)
471
$self->{'transactions'} = 1; # Transactions enabled
473
if (defined($main::opt_create_options) &&
474
$main::opt_create_options =~ /engine=bdb/i)
476
$self->{'transactions'} = 1; # Transactions enabled
484
# Get the version number of the database
490
my ($dbh,$sth,$version,@row);
492
$dbh=$self->connect();
493
$sth = $dbh->prepare("select VERSION()") or die $DBI::errstr;
494
$version="Drizzle 0.?";
495
if ($sth->execute && (@row = $sth->fetchrow_array))
497
$row[0] =~ s/-/ /g; # To get better tables with long names
498
$version="Drizzle $row[0]";
502
$sth = $dbh->prepare("show status like 'ssl_version'") or die $DBI::errstr;
503
if ($sth->execute && (@row = $sth->fetchrow_array) && $row[1])
505
$version .= "/$row[1]";
509
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
514
# Connection with optional disabling of logging
521
$dbh=DBI->connect($self->{'data_source_no_schema'}, $main::opt_user,
522
$main::opt_password,{ PrintError => 0}) ||
523
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source_no_schema'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
525
my $query= q(select 1 from schemata where schema_name = 'test');
526
my $sth= $dbh->prepare($query);
528
my $res= $sth->fetchrow_arrayref();
530
print "'test' schema doesn't exist. creating 'test' schema...";
531
$dbh->do('create database test');
537
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
538
$main::opt_password,{ PrintError => 0}) ||
539
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
545
# Returns a list of statements to create a table
546
# The field types are in ANSI SQL format.
548
# If one uses $main::opt_fast then one is allowed to use
549
# non standard types to get better speed.
553
# Returns a list of statements to create a table
554
# The field types are in ANSI SQL format.
559
my($self,$table_name,$fields,$index) = @_;
562
$query="create table $table_name (";
563
foreach $field (@$fields)
565
$field =~ s/mediumint/integer/i;
566
$field =~ s/tinyint/integer/i;
567
$field =~ s/smallint/integer/i;
568
$field =~ s/longint/integer/i;
569
$field =~ s/integer\(\d+\)/integer/i;
570
$field =~ s/int\(\d+\)/int/i;
571
$query.= $field . ',';
573
foreach $index (@$index)
575
$query.= $index . ',';
577
substr($query,-1)=")"; # Remove last ',';
578
$query.=" $options" if (defined($options));
579
$query.=" $main::opt_create_options" if (defined($main::opt_create_options));
580
print "In Drizzle create $query\n" if ($opt_debug);
581
push(@queries,$query);
586
my ($self,$dbname, $file, $dbh) = @_;
589
$file =~ s|\\|/|g; # Change Win32 names to Unix syntax
590
$command = "load data infile '$file' into table $dbname columns optionally enclosed by '\\'' terminated by ','";
591
# print "$command\n";
592
$sth = $dbh->do($command) or die $DBI::errstr;
593
return $sth; # Contains number of rows
597
# Do any conversions to the ANSI SQL query so that the database can handle it
606
my ($self,$table,$index) = @_;
607
return "DROP INDEX $index ON $table";
611
# Abort if the server has crashed
613
# 1 question should be retried
616
sub abort_if_fatal_error
622
# This should return 1 if we to do disconnect / connect when doing
626
sub small_rollback_segment
632
# reconnect on errors (needed mainly be crash-me)
635
sub reconnect_on_errors
642
my ($self,$cmd) = @_;
647
# Optimize tables for better performance
652
my ($self,$full_vacuum,$dbh_ref,@tables)=@_;
653
my ($loop_time,$end_time,$dbh);
657
$loop_time=new Benchmark;
658
$dbh->do("OPTIMIZE TABLE " . join(',',@tables)) || die "Got error: $DBI::errstr when executing 'OPTIMIZE TABLE'\n";
659
$end_time=new Benchmark;
660
print "Time for book-keeping (1): " .
661
Benchmark::timestr(Benchmark::timediff($end_time, $loop_time),"all") . "\n\n";
665
#############################################################################
666
# Definitions for mSQL
667
#############################################################################
673
my ($type,$host,$database)= @_;
678
$self->{'cmp_name'} = "msql";
679
$self->{'data_source'} = "DBI:mSQL:$database:$host";
680
$self->{'limits'} = \%limits;
681
$self->{'double_quotes'} = 0;
682
$self->{'drop_attr'} = "";
683
$self->{'transactions'} = 0; # No transactions
684
$self->{'blob'} = "text(" . $limits{'max_text_size'} .")";
685
$self->{'text'} = "text(" . $limits{'max_text_size'} .")";
687
$limits{'max_conditions'} = 74;
688
$limits{'max_columns'} = 75;
689
$limits{'max_tables'} = 65000; # Should be big enough
690
$limits{'max_text_size'} = 32000;
691
$limits{'query_size'} = 65535;
692
$limits{'max_index'} = 5;
693
$limits{'max_index_parts'} = 10;
694
$limits{'max_column_name'} = 35;
696
$limits{'join_optimizer'} = 0; # Can't optimize FROM tables
697
$limits{'load_data_infile'} = 0;
698
$limits{'lock_tables'} = 0;
699
$limits{'functions'} = 0;
700
$limits{'group_functions'} = 0;
701
$limits{'group_distinct_functions'}= 0; # Have count(distinct)
702
$limits{'multi_drop'} = 0;
703
$limits{'select_without_from'}= 0;
704
$limits{'subqueries'} = 0;
705
$limits{'left_outer_join'} = 0;
706
$limits{'table_wildcard'} = 0;
707
$limits{'having_with_alias'} = 0;
708
$limits{'having_with_group'} = 0;
709
$limits{'like_with_column'} = 1;
710
$limits{'order_by_position'} = 1;
711
$limits{'group_by_position'} = 1;
712
$limits{'alter_table'} = 0;
713
$limits{'alter_add_multi_col'}= 0;
714
$limits{'alter_table_dropcol'}= 0;
715
$limits{'group_func_extra_std'} = 0;
716
$limits{'limit'} = 1; # supports the limit attribute
717
$limits{'unique_index'} = 1; # Unique index works or not
718
$limits{'insert_select'} = 0;
720
$limits{'func_odbc_mod'} = 0;
721
$limits{'func_extra_%'} = 0;
722
$limits{'func_odbc_floor'} = 0;
723
$limits{'func_extra_if'} = 0;
724
$limits{'column_alias'} = 0;
726
$limits{'func_extra_in_num'} = 0;
727
$limits{'working_blobs'} = 1; # If big varchar/blobs works
728
$limits{'order_by_unused'} = 1;
729
$limits{'working_all_fields'} = 1;
730
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
735
# Get the version number of the database
741
foreach $dir ("/usr/local/Hughes", "/usr/local/mSQL","/my/local/mSQL",
744
if (-x "$dir/bin/msqladmin")
746
$tmp=`$dir/bin/msqladmin version | grep server`;
747
if ($tmp =~ /^\s*(.*\w)\s*$/)
748
{ # Strip pre- and endspace
750
$tmp =~ s/\s+/ /g; # Remove unnecessary spaces
751
$tmp .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
757
return "mSQL version ???";
765
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
766
$main::opt_password,{ PrintError => 0}) ||
767
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
772
# Can't handle many field types, so we map everything to int and real.
777
my($self,$table_name,$fields,$index) = @_;
778
my($query,@queries,$name,$nr);
780
$query="create table $table_name (";
781
foreach $field (@$fields)
783
$field =~ s/varchar/char/i; # mSQL doesn't have VARCHAR()
784
# mSQL can't handle more than the real basic int types
785
$field =~ s/tinyint|smallint|mediumint|integer/int/i;
786
# mSQL can't handle different visual lengths
787
$field =~ s/int\(\d*\)/int/i;
788
# mSQL doesn't have float, change it to real
789
$field =~ s/float(\(\d*,\d*\)){0,1}/real/i;
790
$field =~ s/double(\(\d*,\d*\)){0,1}/real/i;
791
# mSQL doesn't have blob, it has text instead
792
if ($field =~ / blob/i)
794
$name=$self->{'blob'};
795
$field =~ s/ blob/ $name/;
797
$query.= $field . ',';
799
substr($query,-1)=")"; # Remove last ',';
800
push(@queries,$query);
803
# Prepend table_name to index name because the the name may clash with
804
# a field name. (Should be diffent name space, but this is mSQL...)
806
foreach $index (@$index)
808
# Primary key is unique index in mSQL
809
$index =~ s/primary key/unique index primary/i;
810
if ($index =~ /^unique\s*\(([^\(]*)\)$/i)
813
push(@queries,"create unique index ${table_name}_$nr on $table_name ($1)");
817
if (!($index =~ /^(.*index)\s+(\w*)\s+(\(.*\))$/i))
819
die "Can't parse index information in '$index'\n";
821
push(@queries,"create $1 ${table_name}_$2 on $table_name $3");
829
my($self,$dbname, $file) = @_;
830
print "insert an ascii file isn't supported by mSQL\n";
842
my ($self,$table,$index) = @_;
843
return "DROP INDEX $index FROM $table";
846
sub abort_if_fatal_error
851
sub small_rollback_segment
856
sub reconnect_on_errors
863
my ($self,$cmd) = @_;
867
#############################################################################
868
# Definitions for PostgreSQL #
869
#############################################################################
875
my ($type,$host,$database)= @_;
880
$self->{'cmp_name'} = "pg";
881
$self->{'data_source'} = "DBI:Pg:dbname=$database";
882
$self->{'limits'} = \%limits;
883
$self->{'blob'} = "text";
884
$self->{'text'} = "text";
885
$self->{'double_quotes'} = 1;
886
$self->{'drop_attr'} = "";
887
$self->{'transactions'} = 1; # Transactions enabled
888
$self->{"vacuum"} = 1;
889
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
890
$limits{'load_data_infile'} = 0;
893
$limits{'alter_add_multi_col'}= 0; # alter_add_multi_col ?
894
$limits{'alter_table'} = 1;
895
$limits{'alter_table_dropcol'}= 0;
896
$limits{'column_alias'} = 1;
897
$limits{'func_extra_%'} = 1;
898
$limits{'func_extra_if'} = 0;
899
$limits{'func_extra_in_num'} = 1;
900
$limits{'func_odbc_floor'} = 1;
901
$limits{'func_odbc_mod'} = 1; # Has %
902
$limits{'functions'} = 1;
903
$limits{'group_by_position'} = 1;
904
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
905
$limits{'group_func_extra_std'} = 0;
906
$limits{'group_func_sql_min_str'}= 1; # Can execute MIN() and MAX() on strings
907
$limits{'group_functions'} = 1;
908
$limits{'having_with_alias'} = 0;
909
$limits{'having_with_group'} = 1;
910
$limits{'insert_select'} = 1;
911
$limits{'left_outer_join'} = 1;
912
$limits{'like_with_column'} = 1;
913
$limits{'lock_tables'} = 0; # in ATIS gives this a problem
914
$limits{'max_column_name'} = 128;
915
$limits{'max_columns'} = 1000; # 500 crashes pg 6.3
916
$limits{'max_conditions'} = 9999; # This makes Pg real slow
917
$limits{'max_index'} = 64; # Big enough
918
$limits{'max_index_parts'} = 16;
919
$limits{'max_tables'} = 5000; # 10000 crashes pg 7.0.2
920
$limits{'max_text_size'} = 65000; # Good enough for test
921
$limits{'multi_drop'} = 1;
922
$limits{'order_by_position'} = 1;
923
$limits{'order_by_unused'} = 1;
924
$limits{'query_size'} = 16777216;
925
$limits{'select_without_from'}= 1;
926
$limits{'subqueries'} = 1;
927
$limits{'table_wildcard'} = 1;
928
$limits{'truncate_table'} = 1;
929
$limits{'unique_index'} = 1; # Unique index works or not
930
$limits{'working_all_fields'} = 1;
931
$limits{'working_blobs'} = 1; # If big varchar/blobs works
932
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
937
# couldn't find the option to get the version number
942
$version = "PostgreSQL version ???";
943
foreach $dir ($ENV{'PGDATA'},"/usr/local/pgsql/data", "/usr/local/pg/data")
945
if ($dir && -e "$dir/PG_VERSION")
947
$version= `cat $dir/PG_VERSION`;
951
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
952
return "PostgreSQL $version";
956
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
965
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
966
$main::opt_password,{ PrintError => 0}) ||
967
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
974
my($self,$table_name,$fields,$index) = @_;
975
my($query,@queries,$name,$in,$indfield,$table,$nr);
977
$query="create table $table_name (";
978
foreach $field (@$fields)
982
# Allow use of char2, char4, char8 or char16
983
$field =~ s/char(2|4|8|16)/char$1/;
985
# Pg can't handle more than the real basic int types
986
$field =~ s/tinyint|smallint|mediumint|integer/int/;
987
# Pg can't handle different visual lengths
988
$field =~ s/int\(\d*\)/int/;
989
$field =~ s/float\(\d*,\d*\)/float/;
990
$field =~ s/ double/ float/;
991
# $field =~ s/ decimal/ float/i;
992
# $field =~ s/ big_decimal/ float/i;
993
# $field =~ s/ date/ int/i;
994
# Pg doesn't have blob, it has text instead
995
$field =~ s/ blob/ text/;
996
$query.= $field . ',';
998
substr($query,-1)=")"; # Remove last ',';
999
push(@queries,$query);
1000
foreach $index (@$index)
1002
$index =~ s/primary key/unique index primary_key/i;
1003
if ($index =~ /^unique.*\(([^\(]*)\)$/i)
1005
# original: $indfield="using btree (" .$1.")";
1006
# using btree doesn�t seem to work with Postgres anymore; it creates
1007
# the table and adds the index, but it isn�t unique
1008
$indfield=" (" .$1.")";
1010
$table="index_$nr"; $nr++;
1012
elsif ($index =~ /^(.*index)\s+(\w*)\s+(\(.*\))$/i)
1014
# original: $indfield="using btree (" .$1.")";
1017
$table="index_$nr"; $nr++;
1021
die "Can't parse index information in '$index'\n";
1023
push(@queries,"create $in ${table_name}_$table on $table_name $indfield");
1030
my ($self,$dbname, $file, $dbh) = @_;
1031
my ($command, $sth);
1034
# copy [binary] <class_name> [with oids]
1035
# {to|from} {<filename>|stdin|stdout} [using delimiters <delim>]
1036
print "The ascii files aren't correct for postgres ....!!!\n";
1037
$command = "copy $dbname from '$file' using delimiters ','";
1039
$sth = $dbh->do($command) or die $DBI::errstr;
1044
# As postgreSQL wants A % B instead of standard mod(A,B) we have to map
1045
# This will not handle all cases, but as the benchmarks doesn't use functions
1046
# inside MOD() the following should work
1048
# PostgreSQL cant handle count(*) or even count(1), but it can handle
1049
# count(1+1) sometimes. ==> this is solved in PostgreSQL 6.3
1051
# PostgreSQL 6.5 is supporting MOD.
1054
my($self,$sql) = @_;
1055
my(@select,$change);
1056
# if you use PostgreSQL 6.x and x is lower as 5 then uncomment the line below.
1057
# $sql =~ s/mod\(([^,]*),([^\)]*)\)/\($1 % $2\)/gi;
1059
# if you use PostgreSQL 6.1.x uncomment the lines below
1060
# if ($sql =~ /select\s+count\(\*\)\s+from/i) {
1062
# elsif ($sql =~ /count\(\*\)/i)
1064
# if ($sql =~ /select\s+(.*)\s+from/i)
1066
# @select = split(/,/,$1);
1067
# if ($select[0] =~ /(.*)\s+as\s+\w+$/i)
1073
# $change = $select[0];
1076
# if (($change =~ /count/i) || ($change eq "")) {
1079
# $sql =~ s/count\(\*\)/count($change)/gi;
1087
my ($self,$table,$index) = @_;
1088
return "DROP INDEX $index";
1091
sub abort_if_fatal_error
1093
return 1 if ($DBI::errstr =~ /sent to backend, but backend closed/i);
1097
sub small_rollback_segment
1102
sub reconnect_on_errors
1109
my ($self,$cmd) = @_;
1115
my ($self,$full_vacuum,$dbh_ref,@tables)=@_;
1116
my ($loop_time,$end_time,$dbh,$table);
1117
if (defined($full_vacuum))
1119
$$dbh_ref->disconnect; $$dbh_ref= $self->connect();
1122
$loop_time=new Benchmark;
1125
foreach $table (@tables)
1127
$dbh->do("vacuum analyze $table") || die "Got error: $DBI::errstr when executing 'vacuum analyze $table'\n";
1128
$dbh->do("vacuum $table") || die "Got error: $DBI::errstr when executing 'vacuum'\n";
1133
# $dbh->do("vacuum pg_attributes") || die "Got error: $DBI::errstr when executing 'vacuum'\n";
1134
# $dbh->do("vacuum pg_index") || die "Got error: $DBI::errstr when executing 'vacuum'\n";
1135
$dbh->do("vacuum analyze") || die "Got error: $DBI::errstr when executing 'vacuum analyze'\n";
1136
$dbh->do("vacuum") || die "Got error: $DBI::errstr when executing 'vacuum'\n";
1138
$end_time=new Benchmark;
1139
print "Time for book-keeping (1): " .
1140
Benchmark::timestr(Benchmark::timediff($end_time, $loop_time),"all") . "\n\n";
1141
$dbh->disconnect; $$dbh_ref= $self->connect();
1145
#############################################################################
1146
# Definitions for Solid
1147
#############################################################################
1153
my ($type,$host,$database)= @_;
1158
$self->{'cmp_name'} = "solid";
1159
$self->{'data_source'} = "DBI:Solid:";
1160
$self->{'limits'} = \%limits;
1161
$self->{'blob'} = "long varchar";
1162
$self->{'text'} = "long varchar";
1163
$self->{'double_quotes'} = 1;
1164
$self->{'drop_attr'} = "";
1165
$self->{'transactions'} = 1; # Transactions enabled
1167
$limits{'max_conditions'} = 9999; # Probably big enough
1168
$limits{'max_columns'} = 2000; # From crash-me
1169
$limits{'max_tables'} = 65000; # Should be big enough
1170
$limits{'max_text_size'} = 65492; # According to tests
1171
$limits{'query_size'} = 65535; # Probably a limit
1172
$limits{'max_index'} = 64; # Probably big enough
1173
$limits{'max_index_parts'} = 64;
1174
$limits{'max_column_name'} = 80;
1176
$limits{'join_optimizer'} = 1;
1177
$limits{'load_data_infile'} = 0;
1178
$limits{'lock_tables'} = 0;
1179
$limits{'functions'} = 1;
1180
$limits{'group_functions'} = 1;
1181
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
1182
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
1183
$limits{'select_without_from'}= 0; # Can do 'select 1' ?;
1184
$limits{'multi_drop'} = 0;
1185
$limits{'subqueries'} = 1;
1186
$limits{'left_outer_join'} = 1;
1187
$limits{'table_wildcard'} = 1;
1188
$limits{'having_with_alias'} = 0;
1189
$limits{'having_with_group'} = 1;
1190
$limits{'like_with_column'} = 1;
1191
$limits{'order_by_position'} = 0; # 2.30.0018 can this
1192
$limits{'group_by_position'} = 0;
1193
$limits{'alter_table'} = 1;
1194
$limits{'alter_add_multi_col'}= 0;
1195
$limits{'alter_table_dropcol'}= 0;
1197
$limits{'group_func_extra_std'} = 0; # Have group function std().
1199
$limits{'func_odbc_mod'} = 1;
1200
$limits{'func_extra_%'} = 0;
1201
$limits{'func_odbc_floor'} = 1;
1202
$limits{'column_alias'} = 1;
1204
$limits{'func_extra_in_num'} = 1;
1205
$limits{'unique_index'} = 1; # Unique index works or not
1206
$limits{'insert_select'} = 1;
1207
$limits{'working_blobs'} = 1; # If big varchar/blobs works
1208
$limits{'order_by_unused'} = 1;
1209
$limits{'working_all_fields'} = 1;
1210
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
1216
# Get the version number of the database
1222
$version="Solid version ??";
1223
foreach $dir ($ENV{'SOLIDDIR'},"/usr/local/solid", "/my/local/solid")
1225
if ($dir && -e "$dir/bin/solcon")
1227
$version=`$dir/bin/solcon -e"ver" $main::opt_user $main::opt_password | grep Server | sed q`;
1231
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
1236
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
1244
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
1245
$main::opt_password,{ PrintError => 0}) ||
1246
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
1251
# Returns a list of statements to create a table
1252
# The field types are in ANSI SQL format.
1257
my($self,$table_name,$fields,$index) = @_;
1258
my($query,@queries,$nr);
1260
$query="create table $table_name (";
1261
foreach $field (@$fields)
1263
$field =~ s/mediumint/integer/i;
1264
$field =~ s/ double/ float/i;
1265
# Solid doesn't have blob, it has long varchar
1266
$field =~ s/ blob/ long varchar/;
1267
# $field =~ s/ decimal/ float/i;
1268
# $field =~ s/ big_decimal/ float/i;
1269
# $field =~ s/ date/ int/i;
1270
$query.= $field . ',';
1272
substr($query,-1)=")"; # Remove last ',';
1273
push(@queries,$query);
1275
foreach $index (@$index)
1277
if ($index =~ /^primary key/i || $index =~ /^unique/i)
1278
{ # Add to create statement
1279
substr($queries[0],-1,0)="," . $index;
1283
$index =~ /^(.*)\s+(\(.*\))$/;
1284
push(@queries,"create ${1}$nr on $table_name $2");
1291
# there is no sql statement in solid which can do the load from
1292
# an ascii file in the db ... but there is the speedloader program
1293
# an external program which can load the ascii file in the db ...
1294
# the server must be down before using speedloader !!!!
1295
# (in the standalone version)
1296
# it works also with a control file ... that one must be made ....
1298
my ($self, $dbname, $file) = @_;
1300
$speedcmd = '/usr/local/solid/bin/solload';
1301
print "At this moment not supported - solid server must go down \n";
1305
# solid can't handle an alias in a having statement so
1306
# select test as foo from tmp group by foo having foor > 2
1308
# select test as foo from tmp group by foo having test > 2
1311
my($self,$sql) = @_;
1312
my(@select,$tmp,$newhaving,$key,%change);
1314
if ($sql =~ /having\s+/i)
1316
if ($sql =~ /select (.*) from/i)
1318
(@select) = split(/,\s*/, $1);
1319
foreach $tmp (@select)
1321
if ($tmp =~ /(.*)\s+as\s+(\w+)/)
1327
if ($sql =~ /having\s+(\w+)/i)
1330
foreach $key (sort {$a cmp $b} keys %change)
1332
if ($newhaving eq $key)
1334
$newhaving =~ s/$key/$change{$key}/g;
1338
$sql =~ s/(having)\s+(\w+)/$1 $newhaving/i;
1346
my ($self,$table,$index) = @_;
1347
return "DROP INDEX $index";
1350
sub abort_if_fatal_error
1355
sub small_rollback_segment
1362
my ($self,$cmd) = @_;
1366
sub reconnect_on_errors
1371
#############################################################################
1372
# Definitions for Empress
1374
# at this moment DBI:Empress can only handle 200 prepare statements ...
1375
# so Empress can't be tested with the benchmark test :(
1376
#############################################################################
1382
my ($type,$host,$database)= @_;
1387
$self->{'cmp_name'} = "empress";
1388
$self->{'data_source'} = "DBI:EmpressNet:SERVER=$host;Database=/usr/local/empress/rdbms/bin/$database";
1389
$self->{'limits'} = \%limits;
1390
$self->{'blob'} = "text";
1391
$self->{'text'} = "text";
1392
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
1393
$self->{'drop_attr'} = "";
1394
$self->{'transactions'} = 1; # Transactions enabled
1396
$limits{'max_conditions'} = 1258;
1397
$limits{'max_columns'} = 226; # server is disconnecting????
1398
# above this value .... but can handle 2419 columns
1399
# maybe something for crash-me ... but how to check ???
1400
$limits{'max_tables'} = 65000; # Should be big enough
1401
$limits{'max_text_size'} = 4095; # max returned ....
1402
$limits{'query_size'} = 65535; # Not a limit, big enough
1403
$limits{'max_index'} = 64; # Big enough
1404
$limits{'max_index_parts'} = 64; # Big enough
1405
$limits{'max_column_name'} = 31;
1407
$limits{'join_optimizer'} = 1;
1408
$limits{'load_data_infile'} = 0;
1409
$limits{'lock_tables'} = 1;
1410
$limits{'functions'} = 1;
1411
$limits{'group_functions'} = 1;
1412
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
1413
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
1414
$limits{'select_without_from'}= 0;
1415
$limits{'multi_drop'} = 0;
1416
$limits{'subqueries'} = 1;
1417
$limits{'table_wildcard'} = 0;
1418
$limits{'having_with_alias'} = 0; # AS isn't supported in a select
1419
$limits{'having_with_group'} = 1;
1420
$limits{'like_with_column'} = 1;
1421
$limits{'order_by_position'} = 1;
1422
$limits{'group_by_position'} = 0;
1423
$limits{'alter_table'} = 1;
1424
$limits{'alter_add_multi_col'}= 0;
1425
$limits{'alter_table_dropcol'}= 0;
1427
$limits{'group_func_extra_std'}= 0; # Have group function std().
1429
$limits{'func_odbc_mod'} = 0;
1430
$limits{'func_extra_%'} = 1;
1431
$limits{'func_odbc_floor'} = 1;
1432
$limits{'func_extra_if'} = 0;
1433
$limits{'column_alias'} = 0;
1435
$limits{'func_extra_in_num'} = 0;
1436
$limits{'unique_index'} = 1; # Unique index works or not
1437
$limits{'insert_select'} = 1;
1438
$limits{'working_blobs'} = 1; # If big varchar/blobs works
1439
$limits{'order_by_unused'} = 1;
1440
$limits{'working_all_fields'} = 1;
1441
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
1447
# Get the version number of the database
1455
if (-x "/usr/local/empress/rdbms/bin/empvers")
1457
$version=`/usr/local/empress/rdbms/bin/empvers | grep Version`;
1465
$version="Empress version ???";
1468
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
1476
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
1477
$main::opt_password,{ PrintError => 0}) ||
1478
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
1483
my($self,$dbname, $file) = @_;
1485
$command = "insert into $dbname from '$file'";
1486
print "$command\n" if ($opt_debug);
1487
$sth = $dbh->do($command) or die $DBI::errstr;
1493
# Returns a list of statements to create a table
1494
# The field types are in ANSI SQL format.
1499
my($self,$table_name,$fields,$index) = @_;
1500
my($query,@queries,$nr);
1502
$query="create table $table_name (";
1503
foreach $field (@$fields)
1505
$field =~ s/mediumint/int/i;
1506
$field =~ s/tinyint/int/i;
1507
$field =~ s/smallint/int/i;
1508
$field =~ s/longint/int/i;
1509
$field =~ s/integer/int/i;
1510
$field =~ s/ double/ longfloat/i;
1511
# Solid doesn't have blob, it has long varchar
1512
# $field =~ s/ blob/ text(65535,65535,65535,65535)/;
1513
$field =~ s/ blob/ text/;
1514
$field =~ s/ varchar\((\d+)\)/ char($1,3)/;
1515
$field =~ s/ char\((\d+)\)/ char($1,3)/;
1516
# $field =~ s/ decimal/ float/i;
1517
# $field =~ s/ big_decimal/ longfloat/i;
1518
# $field =~ s/ date/ int/i;
1519
$field =~ s/ float(.*)/ float/i;
1520
if ($field =~ / int\((\d+)\)/) {
1522
$field =~ s/ int\(\d+\)/ longinteger/i;
1524
$field =~ s/ int\(\d+\)/ longinteger/i;
1527
$field =~ s/ int/ longinteger/i;
1529
$query.= $field . ',';
1531
substr($query,-1)=")"; # Remove last ',';
1532
push(@queries,$query);
1534
foreach $index (@$index)
1536
# Primary key is unique index in Empress
1537
$index =~ s/primary key/unique index/i;
1538
if ($index =~ /^unique.*\(([^\(]*)\)$/i)
1541
push(@queries,"create unique index ${table_name}_$nr on $table_name ($1)");
1545
if (!($index =~ /^(.*index)\s+(\w*)\s+(\(.*\))$/i))
1547
die "Can't parse index information in '$index'\n";
1549
push(@queries,"create $1 ${table_name}_$2 on $table_name $3");
1555
# empress can't handle an alias and but can handle the number of the
1557
# select test as foo from tmp order by foo
1559
# select test from tmp order by 1
1562
my($self,$sql) = @_;
1563
my(@select,$i,$tmp,$newselect,$neworder,@order,$key,%change);
1564
my($tmp1,$otmp,$tmp2);
1566
if ($sql =~ /\s+as\s+/i)
1568
if ($sql =~ /select\s+(.*)\s+from/i) {
1570
(@select) = split(/,\s*/, $1);
1572
foreach $tmp (@select) {
1573
if ($tmp =~ /\s+as\s+(\w+)/) {
1579
$newselect =~ s/\s+as\s+(\w+)//gi;
1581
if ($sql =~ /order\s+by\s+(.*)$/i) {
1582
(@order) = split(/,\s*/, $1);
1583
foreach $otmp (@order) {
1584
foreach $key (sort {$a cmp $b} keys %change) {
1585
if ($otmp eq $key) {
1586
$neworder .= "$tmp1"."$change{$key}";
1589
} elsif ($otmp =~ /(\w+)\s+(.+)$/) {
1591
$neworder .= "$tmp1"."$change{$key} $2";
1597
$neworder .= "$tmp1"."$otmp";
1603
$sql =~ s/(select)\s+(.*)\s+(from)/$1 $newselect $3/i;
1604
$sql =~ s/(order\s+by)\s+(.*)$/$1 $neworder/i;
1611
my ($self,$cmd) = @_;
1612
$cmd =~ s/\'\'/\' \'/g;
1619
my ($self,$table,$index) = @_;
1620
return "DROP INDEX $index";
1623
# This is a because of the 200 statement problem with DBI-Empress
1625
sub abort_if_fatal_error
1627
if ($DBI::errstr =~ /Overflow of table of prepared statements/i)
1629
print "Overflow of prepared statements ... killing the process\n";
1635
sub small_rollback_segment
1640
sub reconnect_on_errors
1645
#############################################################################
1646
# Definitions for Oracle
1647
#############################################################################
1653
my ($type,$host,$database)= @_;
1658
$self->{'cmp_name'} = "Oracle";
1659
$self->{'data_source'} = "DBI:Oracle:$database";
1660
$self->{'limits'} = \%limits;
1661
$self->{'blob'} = "long";
1662
$self->{'text'} = "long";
1663
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
1664
$self->{'drop_attr'} = "";
1665
$self->{'transactions'} = 1; # Transactions enabled
1666
$self->{"vacuum"} = 1;
1668
$limits{'max_conditions'} = 9999; # (Actually not a limit)
1669
$limits{'max_columns'} = 254; # Max number of columns in table
1670
$limits{'max_tables'} = 65000; # Should be big enough
1671
$limits{'max_text_size'} = 2000; # Limit for blob test-connect
1672
$limits{'query_size'} = 65525; # Max size with default buffers.
1673
$limits{'max_index'} = 16; # Max number of keys
1674
$limits{'max_index_parts'} = 16; # Max segments/key
1675
$limits{'max_column_name'} = 32; # max table and column name
1677
$limits{'truncate_table'} = 1;
1678
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
1679
$limits{'load_data_infile'} = 0; # Has load data infile
1680
$limits{'lock_tables'} = 0; # Has lock tables
1681
$limits{'functions'} = 1; # Has simple functions (+/-)
1682
$limits{'group_functions'} = 1; # Have group functions
1683
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
1684
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
1685
$limits{'select_without_from'}= 0;
1686
$limits{'multi_drop'} = 0;
1687
$limits{'subqueries'} = 1;
1688
$limits{'left_outer_join'} = 0; # This may be fixed in the query module
1689
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
1690
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING
1691
$limits{'having_with_group'} = 1; # Can't use group functions in HAVING
1692
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
1693
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
1694
$limits{'group_by_position'} = 0;
1695
$limits{'alter_table'} = 1;
1696
$limits{'alter_add_multi_col'}= 0;
1697
$limits{'alter_table_dropcol'}= 0;
1699
$limits{'group_func_extra_std'} = 0; # Have group function std().
1701
$limits{'func_odbc_mod'} = 0; # Oracle has problem with mod()
1702
$limits{'func_extra_%'} = 0; # Has % as alias for mod()
1703
$limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function
1704
$limits{'func_extra_if'} = 0; # Have function if.
1705
$limits{'column_alias'} = 1; # Alias for fields in select statement.
1706
$limits{'NEG'} = 1; # Supports -id
1707
$limits{'func_extra_in_num'} = 1; # Has function in
1708
$limits{'unique_index'} = 1; # Unique index works or not
1709
$limits{'insert_select'} = 1;
1710
$limits{'working_blobs'} = 1; # If big varchar/blobs works
1711
$limits{'order_by_unused'} = 1;
1712
$limits{'working_all_fields'} = 1;
1713
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
1720
# Get the version number of the database
1726
my ($dbh,$sth,$version,@row);
1728
$dbh=$self->connect();
1729
$sth = $dbh->prepare("select VERSION from product_component_version WHERE PRODUCT like 'Oracle%'") or die $DBI::errstr;
1730
$version="Oracle 7.x";
1731
if ($sth->execute && (@row = $sth->fetchrow_array))
1733
$version="Oracle $row[0]";
1737
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
1745
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
1746
$main::opt_password,{ PrintError => 0}) ||
1747
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
1752
# Returns a list of statements to create a table
1753
# The field types are in ANSI SQL format.
1755
# If one uses $main::opt_fast then one is allowed to use
1756
# non standard types to get better speed.
1761
my($self,$table_name,$fields,$index) = @_;
1762
my($query,@queries,$ind,@keys);
1764
$query="create table $table_name (";
1765
foreach $field (@$fields)
1767
$field =~ s/ character\((\d+)\)/ char\($1\)/i;
1768
$field =~ s/ character varying\((\d+)\)/ varchar\($1\)/i;
1769
$field =~ s/ char varying\((\d+)\)/ varchar\($1\)/i;
1770
$field =~ s/ integer/ number\(38\)/i;
1771
$field =~ s/ int/ number\(38\)/i;
1772
$field =~ s/ tinyint/ number\(38\)/i;
1773
$field =~ s/ smallint/ number\(38\)/i;
1774
$field =~ s/ mediumint/ number\(38\)/i;
1775
$field =~ s/ tinynumber\((\d+)\)\((\d+)\)/ number\($1,$2\)/i;
1776
$field =~ s/ smallnumber\((\d+)\)\((\d+)\)/ number\($1,$2\)/i;
1777
$field =~ s/ mediumnumber\((\d+)\)\((\d+)\)/ number\($1,$2\)/i;
1778
$field =~ s/ number\((\d+)\)\((\d+)\)/ number\($1,$2\)/i;
1779
$field =~ s/ numeric\((\d+)\)\((\d+)\)/ number\($1,$2\)/i;
1780
$field =~ s/ decimal\((\d+)\)\((\d+)\)/ number\($1,$2\)/i;
1781
$field =~ s/ dec\((\d+)\)\((\d+)\)/ number\($1,$2\)/i;
1782
$field =~ s/ float/ number/;
1783
$field =~ s/ real/ number/;
1784
$field =~ s/ double precision/ number/;
1785
$field =~ s/ double/ number/;
1786
$field =~ s/ blob/ long/;
1787
$query.= $field . ',';
1790
foreach $ind (@$index)
1793
if ( $ind =~ /\bKEY\b/i ){
1794
push(@keys,"ALTER TABLE $table_name ADD $ind");
1796
my @fields = split(' ',$index);
1797
my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
1798
push(@index,$query);
1801
substr($query,-1)=")"; # Remove last ',';
1802
push(@queries,$query,@keys,@index);
1808
my($self,$dbname, $file) = @_;
1809
print "insert an ascii file isn't supported by Oracle (?)\n";
1814
# Do any conversions to the ANSI SQL query so that the database can handle it
1818
my($self,$sql) = @_;
1824
my ($self,$cmd) = @_;
1825
$cmd =~ s/\'\'/\' \'/g;
1832
my ($self,$table,$index) = @_;
1833
return "DROP INDEX $index";
1837
# Abort if the server has crashed
1839
# 1 question should be retried
1842
sub abort_if_fatal_error
1847
sub small_rollback_segment
1852
sub reconnect_on_errors
1858
# optimize the tables ....
1862
my ($self,$full_vacuum,$dbh_ref)=@_;
1863
my ($loop_time,$end_time,$sth,$dbh);
1865
if (defined($full_vacuum))
1867
$$dbh_ref->disconnect; $$dbh_ref= $self->connect();
1870
$loop_time=new Benchmark;
1871
# first analyze all tables
1872
$sth = $dbh->prepare("select table_name from user_tables") || die "Got error: $DBI::errstr";
1873
$sth->execute || die "Got error: $DBI::errstr when select user_tables";
1874
while (my @r = $sth->fetchrow_array)
1876
$dbh->do("analyze table $r[0] compute statistics") || die "Got error: $DBI::errstr when executing 'analyze table'\n";
1878
# now analyze all indexes ...
1879
$sth = $dbh->prepare("select index_name from user_indexes") || die "Got error: $DBI::errstr";
1880
$sth->execute || die "Got error: $DBI::errstr when select user_indexes";
1881
while (my @r1 = $sth->fetchrow_array)
1883
$dbh->do("analyze index $r1[0] compute statistics") || die "Got error: $DBI::errstr when executing 'analyze index $r1[0]'\n";
1885
$end_time=new Benchmark;
1886
print "Time for book-keeping (1): " .
1887
Benchmark::timestr(Benchmark::timediff($end_time, $loop_time),"all") . "\n\n";
1888
$dbh->disconnect; $$dbh_ref= $self->connect();
1892
#############################################################################
1893
# Definitions for Informix
1894
#############################################################################
1896
package db_Informix;
1900
my ($type,$host,$database)= @_;
1905
$self->{'cmp_name'} = "Informix";
1906
$self->{'data_source'} = "DBI:Informix:$database";
1907
$self->{'limits'} = \%limits;
1908
$self->{'blob'} = "byte in table";
1909
$self->{'text'} = "byte in table";
1910
$self->{'double_quotes'} = 0; # Can handle: 'Walker''s'
1911
$self->{'drop_attr'} = "";
1912
$self->{'transactions'} = 1; # Transactions enabled
1913
$self->{'host'} = $host;
1915
$limits{'NEG'} = 1; # Supports -id
1916
$limits{'alter_table'} = 1;
1917
$limits{'alter_add_multi_col'}= 0;
1918
$limits{'alter_table_dropcol'}= 1;
1919
$limits{'column_alias'} = 1; # Alias for fields in select statement.
1920
$limits{'func_extra_%'} = 0; # Has % as alias for mod()
1921
$limits{'func_extra_if'} = 0; # Have function if.
1922
$limits{'func_extra_in_num'}= 0; # Has function in
1923
$limits{'func_odbc_floor'} = 0; # Has func_odbc_floor function
1924
$limits{'func_odbc_mod'} = 1; # Have function mod.
1925
$limits{'functions'} = 1; # Has simple functions (+/-)
1926
$limits{'group_by_position'} = 1; # Can use 'GROUP BY 1'
1927
$limits{'group_by_alias'} = 0; # Can use 'select a as ab from x GROUP BY ab'
1928
$limits{'group_func_extra_std'} = 0; # Have group function std().
1929
$limits{'group_functions'} = 1; # Have group functions
1930
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
1931
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
1932
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING
1933
$limits{'having_with_group'}= 1; # Can't use group functions in HAVING
1934
$limits{'join_optimizer'} = 1; # Can optimize FROM tables (always 1 only for msql)
1935
$limits{'left_outer_join'} = 0; # Supports left outer joins (ANSI)
1936
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
1937
$limits{'load_data_infile'} = 0; # Has load data infile
1938
$limits{'lock_tables'} = 1; # Has lock tables
1939
$limits{'max_conditions'} = 1214; # (Actually not a limit)
1940
$limits{'max_column_name'} = 18; # max table and column name
1941
$limits{'max_columns'} = 994; # Max number of columns in table
1942
$limits{'max_tables'} = 65000; # Should be big enough
1943
$limits{'max_index'} = 64; # Max number of keys
1944
$limits{'max_index_parts'} = 15; # Max segments/key
1945
$limits{'max_text_size'} = 65535; # Max size with default buffers. ??
1946
$limits{'multi_drop'} = 0; # Drop table can take many tables
1947
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
1948
$limits{'query_size'} = 32766; # Max size with default buffers.
1949
$limits{'select_without_from'}= 0; # Can do 'select 1';
1950
$limits{'subqueries'} = 1; # Doesn't support sub-queries.
1951
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
1952
$limits{'unique_index'} = 1; # Unique index works or not
1953
$limits{'insert_select'} = 1;
1954
$limits{'working_blobs'} = 1; # If big varchar/blobs works
1955
$limits{'order_by_unused'} = 1;
1956
$limits{'working_all_fields'} = 1;
1957
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
1963
# Get the version number of the database
1969
my ($dbh,$sth,$version,@row);
1971
$ENV{'INFORMIXSERVER'} = $self->{'host'};
1972
$dbh=$self->connect();
1973
$sth = $dbh->prepare("SELECT owner FROM systables WHERE tabname = ' VERSION'")
1974
or die $DBI::errstr;
1975
$version='Informix unknown';
1976
if ($sth->execute && (@row = $sth->fetchrow_array))
1978
$version="Informix $row[0]";
1982
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
1990
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
1991
$main::opt_password,{ PrintError => 0}) ||
1992
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
2003
my($self,$table_name,$fields,$index) = @_;
2004
my($query,@queries,$name,$nr);
2006
$query="create table $table_name (";
2007
foreach $field (@$fields)
2009
# $field =~ s/\btransport_description\b/transport_desc/;
2010
# to overcome limit 18 chars
2011
$field =~ s/tinyint/smallint/i;
2012
$field =~ s/tinyint\(\d+\)/smallint/i;
2013
$field =~ s/mediumint/integer/i;
2014
$field =~ s/mediumint\(\d+\)/integer/i;
2015
$field =~ s/smallint\(\d+\)/smallint/i;
2016
$field =~ s/integer\(\d+\)/integer/i;
2017
$field =~ s/int\(\d+\)/integer/i;
2018
# $field =~ s/\b(?:small)?int(?:eger)?\((\d+)\)/decimal($1)/i;
2019
# $field =~ s/float(\(\d*,\d*\)){0,1}/real/i;
2020
$field =~ s/(float|double)(\(.*?\))?/float/i;
2022
if ($field =~ / blob/i)
2024
$name=$self->{'blob'};
2025
$field =~ s/ blob/ $name/;
2027
$query.= $field . ',';
2029
substr($query,-1)=")"; # Remove last ',';
2030
push(@queries,$query);
2033
foreach $index (@$index)
2035
# Primary key is unique index in Informix
2036
$index =~ s/primary key/unique index primary/i;
2037
if ($index =~ /^unique\s*\(([^\(]*)\)$/i)
2040
push(@queries,"create unique index ${table_name}_$nr on $table_name ($1)");
2044
if (!($index =~ /^(.*index)\s+(\w*)\s+(\(.*\))$/i))
2046
die "Can't parse index information in '$index'\n";
2048
### push(@queries,"create $1 ${table_name}_$2 on $table_name $3");
2050
push(@queries,"create $1 ${table_name}_$nr on $table_name $3");
2056
# Some test needed this
2060
my($self,$sql) = @_;
2067
my ($self,$cmd) = @_;
2076
my ($self,$table,$index) = @_;
2077
return "DROP INDEX $index";
2081
# Abort if the server has crashed
2083
# 1 question should be retried
2086
sub abort_if_fatal_error
2091
sub small_rollback_segment
2096
sub reconnect_on_errors
2102
#############################################################################
2103
# Configuration for Access
2104
#############################################################################
2110
my ($type,$host,$database)= @_;
2115
$self->{'cmp_name'} = "access";
2116
$self->{'data_source'} = "DBI:ODBC:$database";
2117
if (defined($host) && $host ne "")
2119
$self->{'data_source'} .= ":$host";
2121
$self->{'limits'} = \%limits;
2122
$self->{'blob'} = "blob";
2123
$self->{'text'} = "blob"; # text ?
2124
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
2125
$self->{'drop_attr'} = "";
2126
$self->{'transactions'} = 1; # Transactions enabled
2128
$limits{'max_conditions'} = 97; # We get 'Query is too complex'
2129
$limits{'max_columns'} = 255; # Max number of columns in table
2130
$limits{'max_tables'} = 65000; # Should be big enough
2131
$limits{'max_text_size'} = 255; # Max size with default buffers.
2132
$limits{'query_size'} = 65535; # Not a limit, big enough
2133
$limits{'max_index'} = 32; # Max number of keys
2134
$limits{'max_index_parts'} = 10; # Max segments/key
2135
$limits{'max_column_name'} = 64; # max table and column name
2137
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
2138
$limits{'load_data_infile'} = 0; # Has load data infile
2139
$limits{'lock_tables'} = 0; # Has lock tables
2140
$limits{'functions'} = 1; # Has simple functions (+/-)
2141
$limits{'group_functions'} = 1; # Have group functions
2142
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
2143
$limits{'group_distinct_functions'}= 0; # Have count(distinct)
2144
$limits{'select_without_from'}= 1; # Can do 'select 1';
2145
$limits{'multi_drop'} = 0; # Drop table can take many tables
2146
$limits{'subqueries'} = 1; # Supports sub-queries.
2147
$limits{'left_outer_join'} = 1; # Supports left outer joins
2148
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
2149
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING
2150
$limits{'having_with_group'} = 1; # Can use group functions in HAVING
2151
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
2152
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
2153
$limits{'group_by_position'} = 0; # Can use 'GROUP BY 1'
2154
$limits{'alter_table'} = 1;
2155
$limits{'alter_add_multi_col'}= 2; #Have ALTER TABLE t add a int, b int;
2156
$limits{'alter_table_dropcol'}= 1;
2158
$limits{'group_func_extra_std'} = 0; # Have group function std().
2160
$limits{'func_odbc_mod'} = 0; # Have function mod.
2161
$limits{'func_extra_%'} = 0; # Has % as alias for mod()
2162
$limits{'func_odbc_floor'} = 0; # Has func_odbc_floor function
2163
$limits{'func_extra_if'} = 0; # Have function if.
2164
$limits{'column_alias'} = 1; # Alias for fields in select statement.
2165
$limits{'NEG'} = 1; # Supports -id
2166
$limits{'func_extra_in_num'} = 1; # Has function in
2167
$limits{'unique_index'} = 1; # Unique index works or not
2168
$limits{'insert_select'} = 1;
2169
$limits{'working_blobs'} = 1; # If big varchar/blobs works
2170
$limits{'order_by_unused'} = 1;
2171
$limits{'working_all_fields'} = 1;
2172
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
2177
# Get the version number of the database
2183
my $version="Access 2000";
2184
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
2185
return $version; #DBI/ODBC can't return the server version
2192
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
2193
$main::opt_password,{ PrintError => 0}) ||
2194
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
2199
# Returns a list of statements to create a table
2200
# The field types are in ANSI SQL format.
2205
my($self,$table_name,$fields,$index) = @_;
2206
my($query,@queries,$nr);
2208
$query="create table $table_name (";
2209
foreach $field (@$fields)
2211
$field =~ s/mediumint/integer/i;
2212
$field =~ s/tinyint/smallint/i;
2213
$field =~ s/float\(\d+,\d+\)/float/i;
2214
$field =~ s/integer\(\d+\)/integer/i;
2215
$field =~ s/smallint\(\d+\)/smallint/i;
2216
$field =~ s/int\(\d+\)/integer/i;
2217
$field =~ s/blob/text/i;
2218
$query.= $field . ',';
2220
substr($query,-1)=")"; # Remove last ',';
2221
push(@queries,$query);
2223
foreach $index (@$index)
2225
$ext="WITH DISALLOW NULL";
2226
if (($index =~ s/primary key/unique index primary_key/i))
2228
$ext="WITH PRIMARY;"
2230
if ($index =~ /^unique.*\(([^\(]*)\)$/i)
2233
$index="unique index ${table_name}_$nr ($1)";
2235
$index =~ /^(.*)\s+(\(.*\))$/;
2236
push(@queries,"create ${1} on $table_name $2");
2242
# Do any conversions to the ANSI SQL query so that the database can handle it
2246
my($self,$sql) = @_;
2252
my ($self,$table,$index) = @_;
2253
return "DROP INDEX $index ON $table";
2257
# Abort if the server has crashed
2259
# 1 question should be retried
2262
sub abort_if_fatal_error
2264
return 1 if (($DBI::errstr =~ /The database engine couldn\'t lock table/i) ||
2265
($DBI::errstr =~ /niet vergrendelen. De tabel is momenteel in gebruik /i) ||
2266
($DBI::errstr =~ /Den anv.* redan av en annan/i) ||
2267
($DBI::errstr =~ /non-exclusive access/));
2271
sub small_rollback_segment
2276
sub reconnect_on_errors
2283
my ($self,$cmd) = @_;
2287
#############################################################################
2288
# Configuration for Microsoft SQL server
2289
#############################################################################
2295
my ($type,$host,$database)= @_;
2300
$self->{'cmp_name'} = "ms-sql";
2301
$self->{'data_source'} = "DBI:ODBC:$database";
2302
if (defined($host) && $host ne "")
2304
$self->{'data_source'} .= ":$host";
2306
$self->{'limits'} = \%limits;
2307
$self->{'blob'} = "text";
2308
$self->{'text'} = "text";
2309
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
2310
$self->{'drop_attr'} = "";
2311
$self->{'transactions'} = 1; # Transactions enabled
2313
$limits{'max_conditions'} = 1030; # We get 'Query is too complex'
2314
$limits{'max_columns'} = 250; # Max number of columns in table
2315
$limits{'max_tables'} = 65000; # Should be big enough
2316
$limits{'max_text_size'} = 9830; # Max size with default buffers.
2317
$limits{'query_size'} = 9830; # Max size with default buffers.
2318
$limits{'max_index'} = 64; # Max number of keys
2319
$limits{'max_index_parts'} = 15; # Max segments/key
2320
$limits{'max_column_name'} = 30; # max table and column name
2322
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
2323
$limits{'load_data_infile'} = 0; # Has load data infile
2324
$limits{'lock_tables'} = 0; # Has lock tables
2325
$limits{'functions'} = 1; # Has simple functions (+/-)
2326
$limits{'group_functions'} = 1; # Have group functions
2327
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
2328
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
2329
$limits{'select_without_from'}= 1; # Can do 'select 1';
2330
$limits{'multi_drop'} = 1; # Drop table can take many tables
2331
$limits{'subqueries'} = 1; # Supports sub-queries.
2332
$limits{'left_outer_join'} = 1; # Supports left outer joins
2333
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
2334
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING
2335
$limits{'having_with_group'} = 1; # Can't use group functions in HAVING
2336
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
2337
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
2338
$limits{'group_by_position'} = 0; # Can use 'GROUP BY 1'
2339
$limits{'alter_table'} = 1;
2340
$limits{'alter_add_multi_col'}= 0;
2341
$limits{'alter_table_dropcol'}= 0;
2343
$limits{'group_func_extra_std'} = 0; # Have group function std().
2345
$limits{'func_odbc_mod'} = 0; # Have function mod.
2346
$limits{'func_extra_%'} = 1; # Has % as alias for mod()
2347
$limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function
2348
$limits{'func_extra_if'} = 0; # Have function if.
2349
$limits{'column_alias'} = 1; # Alias for fields in select statement.
2350
$limits{'NEG'} = 1; # Supports -id
2351
$limits{'func_extra_in_num'} = 0; # Has function in
2352
$limits{'unique_index'} = 1; # Unique index works or not
2353
$limits{'insert_select'} = 1;
2354
$limits{'working_blobs'} = 1; # If big varchar/blobs works
2355
$limits{'order_by_unused'} = 1;
2356
$limits{'working_all_fields'} = 1;
2357
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
2362
# Get the version number of the database
2368
my($sth,@row, $version);
2369
$version='MS SQL server ?';
2370
$dbh=$self->connect();
2371
$sth = $dbh->prepare("SELECT \@\@VERSION") or die $DBI::errstr;
2372
$sth->execute or die $DBI::errstr;
2373
@row = $sth->fetchrow_array;
2375
@server = split(/\n/,$row[0]);
2377
$version= "$server[0]";
2380
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
2388
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
2389
$main::opt_password,{ PrintError => 0}) ||
2390
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
2395
# Returns a list of statements to create a table
2396
# The field types are in ANSI SQL format.
2401
my($self,$table_name,$fields,$index) = @_;
2402
my($query,@queries,$nr);
2404
$query="create table $table_name (";
2405
foreach $field (@$fields)
2407
$field =~ s/mediumint/integer/i;
2408
$field =~ s/float\(\d+,\d+\)/float/i;
2409
$field =~ s/double\(\d+,\d+\)/float/i;
2410
$field =~ s/double/float/i;
2411
$field =~ s/integer\(\d+\)/integer/i;
2412
$field =~ s/int\(\d+\)/integer/i;
2413
$field =~ s/smallint\(\d+\)/smallint/i;
2414
$field =~ s/smallinteger/smallint/i;
2415
$field =~ s/tinyint\(\d+\)/tinyint/i;
2416
$field =~ s/tinyinteger/tinyint/i;
2417
$field =~ s/blob/text/i;
2418
$query.= $field . ',';
2420
substr($query,-1)=")"; # Remove last ',';
2421
push(@queries,$query);
2423
foreach $index (@$index)
2425
$ext="WITH DISALLOW NULL";
2426
if (($index =~ s/primary key/unique index primary_key/i))
2428
$ext="WITH PRIMARY;"
2430
if ($index =~ /^unique.*\(([^\(]*)\)$/i)
2433
$index="unique index ${table_name}_$nr ($1)";
2435
$index =~ /^(.*)\s+(\(.*\))$/;
2436
push(@queries,"create ${1} on $table_name $2");
2442
# Do any conversions to the ANSI SQL query so that the database can handle it
2446
my($self,$sql) = @_;
2452
my ($self,$table,$index) = @_;
2453
return "DROP INDEX $table.$index";
2457
# Abort if the server has crashed
2459
# 1 question should be retried
2462
sub abort_if_fatal_error
2467
sub small_rollback_segment
2472
sub reconnect_on_errors
2479
my ($self,$cmd) = @_;
2483
#############################################################################
2484
# Configuration for Sybase
2485
#############################################################################
2490
my ($type,$host,$database)= @_;
2495
$self->{'cmp_name'} = "sybase";
2496
$self->{'data_source'} = "DBI:Sybase:database=$database";
2497
if (defined($host) && $host ne "")
2499
$self->{'data_source'} .= ";hostname=$host";
2501
$self->{'limits'} = \%limits;
2502
$self->{'blob'} = "text";
2503
$self->{'text'} = "text";
2504
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
2505
$self->{'drop_attr'} = "";
2506
$self->{'transactions'} = 1; # Transactions enabled
2507
$self->{"vacuum"} = 1;
2509
$limits{'max_conditions'} = 1030; # We get 'Query is too complex'
2510
$limits{'max_columns'} = 250; # Max number of columns in table
2511
$limits{'max_tables'} = 65000; # Should be big enough
2512
$limits{'max_text_size'} = 9830; # Max size with default buffers.
2513
$limits{'query_size'} = 9830; # Max size with default buffers.
2514
$limits{'max_index'} = 64; # Max number of keys
2515
$limits{'max_index_parts'} = 15; # Max segments/key
2516
$limits{'max_column_name'} = 30; # max table and column name
2518
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
2519
$limits{'load_data_infile'} = 0; # Has load data infile
2520
$limits{'lock_tables'} = 0; # Has lock tables
2521
$limits{'functions'} = 1; # Has simple functions (+/-)
2522
$limits{'group_functions'} = 1; # Have group functions
2523
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
2524
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
2525
$limits{'select_without_from'}= 1; # Can do 'select 1';
2526
$limits{'multi_drop'} = 1; # Drop table can take many tables
2527
$limits{'subqueries'} = 1; # Supports sub-queries.
2528
$limits{'left_outer_join'} = 1; # Supports left outer joins
2529
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
2530
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING
2531
$limits{'having_with_group'} = 1; # Can't use group functions in HAVING
2532
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
2533
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
2534
$limits{'group_by_position'} = 0; # Can use 'GROUP BY 1'
2535
$limits{'alter_table'} = 1;
2536
$limits{'alter_add_multi_col'}= 0;
2537
$limits{'alter_table_dropcol'}= 0;
2539
$limits{'group_func_extra_std'} = 0; # Have group function std().
2541
$limits{'func_odbc_mod'} = 0; # Have function mod.
2542
$limits{'func_extra_%'} = 1; # Has % as alias for mod()
2543
$limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function
2544
$limits{'func_extra_if'} = 0; # Have function if.
2545
$limits{'column_alias'} = 1; # Alias for fields in select statement.
2546
$limits{'NEG'} = 1; # Supports -id
2547
$limits{'func_extra_in_num'} = 0; # Has function in
2548
$limits{'unique_index'} = 1; # Unique index works or not
2549
$limits{'insert_select'} = 1;
2550
$limits{'working_blobs'} = 1; # If big varchar/blobs works
2551
$limits{'order_by_unused'} = 1;
2552
$limits{'working_all_fields'} = 1;
2553
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
2558
# Get the version number of the database
2564
my ($dbh,$sth,$version,@row);
2566
$dbh=$self->connect();
2567
$sth = $dbh->prepare('SELECT @@version') or die $DBI::errstr;
2568
$version="Sybase (unknown)";
2569
if ($sth->execute && (@row = $sth->fetchrow_array))
2575
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
2583
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
2584
$main::opt_password,{ PrintError => 0 , AutoCommit => 1}) ||
2585
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
2590
# Returns a list of statements to create a table
2591
# The field types are in ANSI SQL format.
2596
my($self,$table_name,$fields,$index) = @_;
2597
my($query,@queries,$nr);
2599
$query="create table $table_name (";
2600
foreach $field (@$fields)
2602
$field =~ s/mediumint/integer/i;
2603
$field =~ s/float\(\d+,\d+\)/float/i;
2604
$field =~ s/int\(\d+\)/int/i;
2605
$field =~ s/double/float/i;
2606
$field =~ s/integer\(\d+\)/integer/i;
2607
$field =~ s/smallint\(\d+\)/smallint/i;
2608
$field =~ s/tinyint\(\d+\)/tinyint/i;
2609
$field =~ s/blob/text/i;
2610
$query.= $field . ',';
2612
substr($query,-1)=")"; # Remove last ',';
2613
push(@queries,$query);
2615
foreach $index (@$index)
2617
# $ext="WITH DISALLOW NULL";
2618
if (($index =~ s/primary key/unique index primary_key/i))
2620
# $ext="WITH PRIMARY;"
2622
if ($index =~ /^unique.*\(([^\(]*)\)$/i)
2625
$index="unique index ${table_name}_$nr ($1)";
2627
$index =~ /^(.*)\s+(\(.*\))$/;
2628
push(@queries,"create ${1} on $table_name $2");
2634
# Do any conversions to the ANSI SQL query so that the database can handle it
2638
my($self,$sql) = @_;
2644
my ($self,$table,$index) = @_;
2645
return "DROP INDEX $table.$index";
2649
# Abort if the server has crashed
2651
# 1 question should be retried
2654
sub abort_if_fatal_error
2659
sub small_rollback_segment
2664
sub reconnect_on_errors
2671
my ($self,$cmd) = @_;
2676
# optimize the tables ....
2677
# WARNING (from walrus)! This sub will work only from DBD:sybase
2678
# driver. Because if we use ODBC we don't know actual database name
2679
# (but DSN name only)
2682
my ($self,$full_vacuum,$dbh_ref)=@_;
2683
my ($loop_time,$end_time,$dbh);
2685
if (defined($full_vacuum))
2687
$$dbh_ref->disconnect; $$dbh_ref= $self->connect();
2690
$loop_time=new Benchmark;
2691
my (@tables,$sth,$current_table,$current_base);
2692
$dbh->do("dump tran $database with truncate_only");
2693
$sth=$dbh->prepare("sp_tables" ) or die "prepere";
2694
$sth->execute() or die "execute";
2695
while (@row = $sth->fetchrow_array()) {
2696
$current_table = $row[2];
2697
$current_base = $row[0];
2698
next if ($current_table =~ /^sys/);
2699
push(@tables,$current_table) if ($database == $current_base);
2704
foreach $table (@tables) {
2705
# print "$table: \n";
2706
$dbh->do("update statistics $table") or print "Oops!";
2709
# $dbh->do("analyze table ?? compute statistics") || die "Got error: $DBI::errstr when executing 'vacuum'\n";
2710
$end_time=new Benchmark;
2711
print "Time for book-keeping (1): " .
2712
Benchmark::timestr(Benchmark::timediff($end_time, $loop_time),"all") . "\n\n";
2713
$dbh->disconnect; $$dbh_ref= $self->connect();
2719
#############################################################################
2720
# Definitions for Adabas
2721
#############################################################################
2727
my ($type,$host,$database)= @_;
2732
$self->{'cmp_name'} = "Adabas";
2733
$self->{'data_source'} = "DBI:Adabas:$database";
2734
$self->{'limits'} = \%limits;
2735
$self->{'blob'} = "long";
2736
$self->{'text'} = "long";
2737
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
2738
$self->{'drop_attr'} = "";
2739
$self->{'transactions'} = 1; # Transactions enabled
2741
$limits{'max_conditions'} = 50; # (Actually not a limit)
2742
$limits{'max_columns'} = 254; # Max number of columns in table
2743
$limits{'max_tables'} = 65000; # Should be big enough
2744
$limits{'max_text_size'} = 2000; # Limit for blob test-connect
2745
$limits{'query_size'} = 65525; # Max size with default buffers.
2746
$limits{'max_index'} = 16; # Max number of keys
2747
$limits{'max_index_parts'} = 16; # Max segments/key
2748
$limits{'max_column_name'} = 32; # max table and column name
2750
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
2751
$limits{'load_data_infile'} = 0; # Has load data infile
2752
$limits{'lock_tables'} = 0; # Has lock tables
2753
$limits{'functions'} = 1; # Has simple functions (+/-)
2754
$limits{'group_functions'} = 1; # Have group functions
2755
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
2756
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
2757
$limits{'select_without_from'}= 0;
2758
$limits{'multi_drop'} = 0;
2759
$limits{'subqueries'} = 1;
2760
$limits{'left_outer_join'} = 0; # This may be fixed in the query module
2761
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
2762
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING
2763
$limits{'having_with_group'} = 1; # Can't use group functions in HAVING
2764
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
2765
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
2766
$limits{'group_by_position'} = 1;
2767
$limits{'alter_table'} = 1;
2768
$limits{'alter_add_multi_col'}= 2; #Have ALTER TABLE t add a int, b int;
2769
$limits{'alter_table_dropcol'}= 1;
2771
$limits{'group_func_extra_std'} = 0; # Have group function std().
2773
$limits{'func_odbc_mod'} = 0; # Oracle has problem with mod()
2774
$limits{'func_extra_%'} = 0; # Has % as alias for mod()
2775
$limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function
2776
$limits{'func_extra_if'} = 0; # Have function if.
2777
$limits{'column_alias'} = 1; # Alias for fields in select statement.
2778
$limits{'NEG'} = 1; # Supports -id
2779
$limits{'func_extra_in_num'} = 1; # Has function in
2780
$limits{'unique_index'} = 1; # Unique index works or not
2781
$limits{'insert_select'} = 1;
2782
$limits{'working_blobs'} = 1; # If big varchar/blobs works
2783
$limits{'order_by_unused'} = 1;
2784
$limits{'working_all_fields'} = 1;
2785
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
2792
# Get the version number of the database
2798
my ($dbh,$sth,$version,@row);
2800
$dbh=$self->connect();
2801
$sth = $dbh->prepare("SELECT KERNEL FROM VERSIONS") or die $DBI::errstr;
2802
$version="Adabas (unknown)";
2803
if ($sth->execute && (@row = $sth->fetchrow_array)
2804
&& $row[0] =~ /([\d\.]+)/)
2806
$version="Adabas $1";
2810
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
2818
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
2819
$main::opt_password,{ PrintError => 0}) ||
2820
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
2825
# Returns a list of statements to create a table
2826
# The field types are in ANSI SQL format.
2828
# If one uses $main::opt_fast then one is allowed to use
2829
# non standard types to get better speed.
2834
my($self,$table_name,$fields,$index) = @_;
2835
my($query,@queries,$ind,@keys);
2837
$query="create table $table_name (";
2838
foreach $field (@$fields)
2840
$field =~ s/CHARACTER\s+VARYING/VARCHAR/i;
2841
$field =~ s/TINYINT/SMALLINT/i;
2842
$field =~ s/MEDIUMINT/INT/i;
2843
$field =~ s/SMALLINT\s*\(\d+\)/SMALLINT/i;
2844
$field =~ s/INT\s*\(\d+\)/INT/i;
2845
$field =~ s/BLOB/LONG/i;
2846
$field =~ s/INTEGER\s*\(\d+\)/INTEGER/i;
2847
$field =~ s/FLOAT\s*\((\d+),\d+\)/FLOAT\($1\)/i;
2848
$field =~ s/DOUBLE/FLOAT\(38\)/i;
2849
$field =~ s/DOUBLE\s+PRECISION/FLOAT\(38\)/i;
2850
$query.= $field . ',';
2853
foreach $ind (@$index)
2856
if ( $ind =~ /\bKEY\b/i ){
2857
push(@keys,"ALTER TABLE $table_name ADD $ind");
2859
my @fields = split(' ',$index);
2860
my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
2861
push(@index,$query);
2864
substr($query,-1)=")"; # Remove last ',';
2865
push(@queries,$query,@keys,@index);
2866
#print "query:$query\n";
2872
my($self,$dbname, $file) = @_;
2873
print "insert an ascii file isn't supported by Oracle (?)\n";
2878
# Do any conversions to the ANSI SQL query so that the database can handle it
2882
my($self,$sql) = @_;
2888
my ($self,$table,$index) = @_;
2889
return "DROP INDEX $index";
2893
# Abort if the server has crashed
2895
# 1 question should be retried
2898
sub abort_if_fatal_error
2903
sub small_rollback_segment
2908
sub reconnect_on_errors
2915
my ($self,$cmd) = @_;
2919
#############################################################################
2920
# Configuration for IBM DB2
2921
#############################################################################
2927
my ($type,$host,$database)= @_;
2932
$self->{'cmp_name'} = "DB2";
2933
$self->{'data_source'} = "DBI:ODBC:$database";
2934
if (defined($host) && $host ne "")
2936
$self->{'data_source'} .= ":$host";
2938
$self->{'limits'} = \%limits;
2939
$self->{'blob'} = "varchar(255)";
2940
$self->{'text'} = "varchar(255)";
2941
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
2942
$self->{'drop_attr'} = "";
2943
$self->{'transactions'} = 1; # Transactions enabled
2945
$limits{'max_conditions'} = 418; # We get 'Query is too complex'
2946
$limits{'max_columns'} = 500; # Max number of columns in table
2947
$limits{'max_tables'} = 65000; # Should be big enough
2948
$limits{'max_text_size'} = 254; # Max size with default buffers.
2949
$limits{'query_size'} = 254; # Max size with default buffers.
2950
$limits{'max_index'} = 48; # Max number of keys
2951
$limits{'max_index_parts'} = 15; # Max segments/key
2952
$limits{'max_column_name'} = 18; # max table and column name
2954
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
2955
$limits{'load_data_infile'} = 0; # Has load data infile
2956
$limits{'lock_tables'} = 0; # Has lock tables
2957
$limits{'functions'} = 1; # Has simple functions (+/-)
2958
$limits{'group_functions'} = 1; # Have group functions
2959
$limits{'group_func_sql_min_str'}= 1;
2960
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
2961
$limits{'select_without_from'}= 0; # Can do 'select 1';
2962
$limits{'multi_drop'} = 0; # Drop table can take many tables
2963
$limits{'subqueries'} = 1; # Supports sub-queries.
2964
$limits{'left_outer_join'} = 1; # Supports left outer joins
2965
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
2966
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING
2967
$limits{'having_with_group'} = 1; # Can't use group functions in HAVING
2968
$limits{'like_with_column'} = 0; # Can use column1 LIKE column2
2969
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
2970
$limits{'group_by_position'} = 0; # Can use 'GROUP BY 1'
2971
$limits{'alter_table'} = 1;
2972
$limits{'alter_add_multi_col'}= 0;
2973
$limits{'alter_table_dropcol'}= 0;
2975
$limits{'group_func_extra_std'} = 0; # Have group function std().
2977
$limits{'func_odbc_mod'} = 1; # Have function mod.
2978
$limits{'func_extra_%'} = 0; # Has % as alias for mod()
2979
$limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function
2980
$limits{'func_extra_if'} = 0; # Have function if.
2981
$limits{'column_alias'} = 1; # Alias for fields in select statement.
2982
$limits{'NEG'} = 1; # Supports -id
2983
$limits{'func_extra_in_num'} = 0; # Has function in
2984
$limits{'unique_index'} = 1; # Unique index works or not
2985
$limits{'insert_select'} = 1;
2986
$limits{'working_blobs'} = 1; # If big varchar/blobs works
2987
$limits{'order_by_unused'} = 1;
2988
$limits{'working_all_fields'} = 1;
2989
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
2994
# Get the version number of the database
3000
return "IBM DB2 5"; #DBI/ODBC can't return the server version
3007
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user, $main::opt_password) ||
3008
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
3013
# Returns a list of statements to create a table
3014
# The field types are in ANSI SQL format.
3019
my($self,$table_name,$fields,$index) = @_;
3020
my($query,@queries,$nr);
3022
$query="create table $table_name (";
3023
foreach $field (@$fields)
3025
$field =~ s/mediumint/integer/i;
3026
$field =~ s/float\(\d+,\d+\)/float/i;
3027
$field =~ s/integer\(\d+\)/integer/i;
3028
$field =~ s/int\(\d+\)/integer/i;
3029
$field =~ s/tinyint\(\d+\)/smallint/i;
3030
$field =~ s/tinyint/smallint/i;
3031
$field =~ s/smallint\(\d+\)/smallint/i;
3032
$field =~ s/smallinteger/smallint/i;
3033
$field =~ s/blob/varchar(256)/i;
3034
$query.= $field . ',';
3036
substr($query,-1)=")"; # Remove last ',';
3037
push(@queries,$query);
3039
foreach $index (@$index)
3041
$ext="WITH DISALLOW NULL";
3042
if (($index =~ s/primary key/unique index primary_key/i))
3044
$ext="WITH PRIMARY;"
3046
if ($index =~ /^unique.*\(([^\(]*)\)$/i)
3049
$index="unique index ${table_name}_$nr ($1)";
3051
$index =~ /^(.*)\s+(\(.*\))$/;
3052
push(@queries,"create ${1} on $table_name $2");
3058
# Do any conversions to the ANSI SQL query so that the database can handle it
3062
my($self,$sql) = @_;
3068
my ($self,$table,$index) = @_;
3069
return "DROP INDEX $table.$index";
3073
# Abort if the server has crashed
3075
# 1 question should be retried
3078
sub abort_if_fatal_error
3083
sub small_rollback_segment
3088
sub reconnect_on_errors
3095
my ($self,$cmd) = @_;
3099
#############################################################################
3100
# Configuration for MIMER
3101
#############################################################################
3107
my ($type,$host,$database)= @_;
3112
$self->{'cmp_name'} = "mimer";
3113
$self->{'data_source'} = "DBI:mimer:$database:$host";
3114
$self->{'limits'} = \%limits;
3115
$self->{'blob'} = "binary varying(15000)";
3116
$self->{'text'} = "character varying(15000)";
3117
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
3118
$self->{'drop_attr'} = "";
3119
$self->{'transactions'} = 1; # Transactions enabled
3120
$self->{'char_null'} = "cast(NULL as char(1))";
3121
$self->{'numeric_null'} = "cast(NULL as int)";
3123
$limits{'max_conditions'} = 9999; # (Actually not a limit)
3124
$limits{'max_columns'} = 252; # Max number of columns in table
3125
$limits{'max_tables'} = 65000; # Should be big enough
3126
$limits{'max_text_size'} = 15000; # Max size with default buffers.
3127
$limits{'query_size'} = 1000000; # Max size with default buffers.
3128
$limits{'max_index'} = 32; # Max number of keys
3129
$limits{'max_index_parts'} = 16; # Max segments/key
3130
$limits{'max_column_name'} = 128; # max table and column name
3132
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
3133
$limits{'load_data_infile'} = 1; # Has load data infile
3134
$limits{'lock_tables'} = 0; # Has lock tables
3135
$limits{'functions'} = 1; # Has simple functions (+/-)
3136
$limits{'group_functions'} = 1; # Have group functions
3137
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
3138
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
3139
$limits{'select_without_from'}= 0; # Cannot do 'select 1';
3140
$limits{'multi_drop'} = 0; # Drop table cannot take many tables
3141
$limits{'subqueries'} = 1; # Supports sub-queries.
3142
$limits{'left_outer_join'} = 1; # Supports left outer joins
3143
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
3144
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING
3145
$limits{'having_with_group'} = 1; # Can use group functions in HAVING
3146
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
3147
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
3148
$limits{'group_by_position'} = 0; # Cannot use 'GROUP BY 1'
3149
$limits{'alter_table'} = 1; # Have ALTER TABLE
3150
$limits{'alter_add_multi_col'}= 0; # Have ALTER TABLE t add a int,add b int;
3151
$limits{'alter_table_dropcol'}= 1; # Have ALTER TABLE DROP column
3152
$limits{'insert_multi_value'} = 0; # Does not have INSERT ... values (1,2),(3,4)
3153
$limits{'multi_distinct'} = 0; # Does not allow select count(distinct a),count(distinct b)..
3155
$limits{'group_func_extra_std'} = 0; # Does not have group function std().
3157
$limits{'func_odbc_mod'} = 1; # Have function mod.
3158
$limits{'func_extra_%'} = 0; # Does not have % as alias for mod()
3159
$limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function
3160
$limits{'func_extra_if'} = 0; # Does not have function if.
3161
$limits{'column_alias'} = 1; # Alias for fields in select statement.
3162
$limits{'NEG'} = 1; # Supports -id
3163
$limits{'func_extra_in_num'} = 1; # Has function in
3164
$limits{'limit'} = 0; # Does not support the limit attribute
3165
$limits{'unique_index'} = 1; # Unique index works or not
3166
$limits{'insert_select'} = 1;
3167
$limits{'working_blobs'} = 1; # If big varchar/blobs works
3168
$limits{'order_by_unused'} = 0;
3169
$limits{'working_all_fields'} = 1;
3175
# Get the version number of the database
3181
my ($dbh,$sth,$version,@row);
3183
$dbh=$self->connect();
3185
# Pick up SQLGetInfo option SQL_DBMS_VER (18)
3187
$version = $dbh->func(18, GetInfo);
3189
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
3194
# Connection with optional disabling of logging
3201
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
3202
$main::opt_password,{ PrintError => 0}) ||
3203
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
3205
$dbh->do("SET OPTION LOG_OFF=1,UPDATE_LOG=0") unless $self->{cmp_name} eq 'drizzle';
3210
# Returns a list of statements to create a table
3211
# The field types are in ANSI SQL format.
3213
# If one uses $main::opt_fast then one is allowed to use
3214
# non standard types to get better speed.
3219
my($self,$table_name,$fields,$index,$options) = @_;
3220
my($query,@queries,@indexes);
3222
$query="create table $table_name (";
3223
foreach $field (@$fields)
3225
# $field =~ s/ decimal/ double(10,2)/i;
3226
# $field =~ s/ big_decimal/ double(10,2)/i;
3227
$field =~ s/ double/ double precision/i;
3228
$field =~ s/ tinyint\(.*\)/ smallint/i;
3229
$field =~ s/ smallint\(.*\)/ smallint/i;
3230
$field =~ s/ mediumint/ integer/i;
3231
$field =~ s/ float\(.*\)/ float/i;
3232
# $field =~ s/ date/ int/i; # Because of tcp ?
3233
$query.= $field . ',';
3235
foreach $index (@$index)
3237
if ( $index =~ /\bINDEX\b/i )
3239
my @fields = split(' ',$index);
3240
my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
3241
push(@indexes,$query);
3244
$query.= $index . ',';
3247
substr($query,-1)=")"; # Remove last ',';
3248
$query.=" $options" if (defined($options));
3249
push(@queries,$query,@indexes);
3254
my($self,$dbname, $file) = @_;
3255
print "insert of an ascii file isn't supported by Mimer\n";
3260
# Do any conversions to the ANSI SQL query so that the database can handle it
3264
my($self,$sql) = @_;
3269
my ($self,$table,$index) = @_;
3270
return "DROP INDEX $index";
3274
# Abort if the server has crashed
3276
# 1 question should be retried
3279
sub abort_if_fatal_error
3281
return 1 if ($DBI::errstr =~ /Table locked by another cursor/);
3285
sub small_rollback_segment
3290
sub reconnect_on_errors
3297
my ($self,$cmd) = @_;
3301
#############################################################################
3302
# Configuration for InterBase
3303
#############################################################################
3305
package db_interbase;
3309
my ($type,$host,$database)= @_;
3314
$self->{'cmp_name'} = "interbase";
3315
$self->{'data_source'} = "DBI:InterBase:database=$database;ib_dialect=3";
3316
$self->{'limits'} = \%limits;
3317
$self->{'blob'} = "blob";
3318
$self->{'text'} = "";
3319
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
3320
$self->{'drop_attr'} = "";
3321
$self->{'transactions'} = 1; # Transactions enabled
3322
$self->{'char_null'} = "";
3323
$self->{'numeric_null'} = "";
3325
$limits{'max_conditions'} = 9999; # (Actually not a limit)
3326
$limits{'max_columns'} = 252; # Max number of columns in table
3327
$limits{'max_tables'} = 65000; # Should be big enough
3328
$limits{'max_text_size'} = 15000; # Max size with default buffers.
3329
$limits{'query_size'} = 1000000; # Max size with default buffers.
3330
$limits{'max_index'} = 65000; # Max number of keys
3331
$limits{'max_index_parts'} = 8; # Max segments/key
3332
$limits{'max_column_name'} = 128; # max table and column name
3334
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
3335
$limits{'load_data_infile'} = 0; # Has load data infile
3336
$limits{'lock_tables'} = 0; # Has lock tables
3337
$limits{'functions'} = 1; # Has simple functions (+/-)
3338
$limits{'group_functions'} = 1; # Have group functions
3339
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings
3340
$limits{'group_distinct_functions'}= 1; # Have count(distinct)
3341
$limits{'select_without_from'}= 0; # Cannot do 'select 1';
3342
$limits{'multi_drop'} = 0; # Drop table cannot take many tables
3343
$limits{'subqueries'} = 1; # Supports sub-queries.
3344
$limits{'left_outer_join'} = 1; # Supports left outer joins
3345
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
3346
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING
3347
$limits{'having_with_group'} = 1; # Can use group functions in HAVING
3348
$limits{'like_with_column'} = 0; # Can use column1 LIKE column2
3349
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
3350
$limits{'group_by_position'} = 0; # Cannot use 'GROUP BY 1'
3351
$limits{'alter_table'} = 1; # Have ALTER TABLE
3352
$limits{'alter_add_multi_col'}= 1; # Have ALTER TABLE t add a int,add b int;
3353
$limits{'alter_table_dropcol'}= 1; # Have ALTER TABLE DROP column
3354
$limits{'insert_multi_value'} = 0; # Does not have INSERT ... values (1,2),(3,4)
3356
$limits{'group_func_extra_std'} = 0; # Does not have group function std().
3358
$limits{'func_odbc_mod'} = 0; # Have function mod.
3359
$limits{'func_extra_%'} = 0; # Does not have % as alias for mod()
3360
$limits{'func_odbc_floor'} = 0; # Has func_odbc_floor function
3361
$limits{'func_extra_if'} = 0; # Does not have function if.
3362
$limits{'column_alias'} = 1; # Alias for fields in select statement.
3363
$limits{'NEG'} = 0; # Supports -id
3364
$limits{'func_extra_in_num'} = 0; # Has function in
3365
$limits{'limit'} = 0; # Does not support the limit attribute
3366
$limits{'working_blobs'} = 1; # If big varchar/blobs works
3367
$limits{'order_by_unused'} = 1;
3368
$limits{'working_all_fields'} = 1;
3369
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
3375
# Get the version number of the database
3383
$version='Interbase ?';
3385
$dbh=$self->connect();
3386
eval { $version = $dbh->func('version','ib_database_info')->{'version'}; };
3388
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
3393
# Connection with optional disabling of logging
3400
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
3401
$main::opt_password,{ PrintError => 0, AutoCommit => 1}) ||
3402
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
3408
# Returns a list of statements to create a table
3409
# The field types are in ANSI SQL format.
3411
# If one uses $main::opt_fast then one is allowed to use
3412
# non standard types to get better speed.
3417
my($self,$table_name,$fields,$index,$options) = @_;
3418
my($query,@queries,@keys,@indexes);
3420
$query="create table $table_name (";
3421
foreach $field (@$fields)
3423
# $field =~ s/ big_decimal/ decimal/i;
3424
$field =~ s/ double/ double precision/i;
3425
$field =~ s/ tinyint/ smallint/i;
3426
$field =~ s/ mediumint/ integer/i;
3427
$field =~ s/\bint\b/integer/i;
3428
$field =~ s/ float\(\d,\d\)/ float/i;
3429
$field =~ s/ smallint\(\d\)/ smallint/i;
3430
$field =~ s/ integer\(\d\)/ integer/i;
3431
$query.= $field . ',';
3433
foreach $ind (@$index)
3435
if ( $ind =~ /(\bKEY\b)|(\bUNIQUE\b)/i ){
3436
push(@keys,"ALTER TABLE $table_name ADD $ind");
3438
my @fields = split(' ',$ind);
3439
my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
3440
push(@indexes,$query);
3443
substr($query,-1)=")"; # Remove last ',';
3444
$query.=" $options" if (defined($options));
3445
push(@queries,$query,@keys,@indexes);
3450
my($self,$dbname, $file) = @_;
3451
print "insert of an ascii file isn't supported by InterBase\n";
3456
# Do any conversions to the ANSI SQL query so that the database can handle it
3460
my($self,$sql) = @_;
3465
my ($self,$table,$index) = @_;
3466
return "DROP INDEX $index";
3470
# Abort if the server has crashed
3472
# 1 question should be retried
3475
sub abort_if_fatal_error
3477
return 1 if ($DBI::errstr =~ /Table locked by another cursor/);
3481
sub small_rollback_segment
3486
sub reconnect_on_errors
3493
my ($self,$cmd) = @_;
3497
#############################################################################
3498
# Configuration for FrontBase
3499
#############################################################################
3501
package db_FrontBase;
3505
my ($type,$host,$database)= @_;
3510
$self->{'cmp_name'} = "FrontBase";
3511
$self->{'data_source'} = "DBI:FB:dbname=$database;host=$host";
3512
$self->{'limits'} = \%limits;
3513
$self->{'blob'} = "varchar(8000000)";
3514
$self->{'text'} = "varchar(8000000)";
3515
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
3516
$self->{'drop_attr'} = ' restrict';
3517
$self->{'transactions'} = 1; # Transactions enabled
3518
$self->{'error_on_execute_means_zero_rows'}=1;
3520
$limits{'max_conditions'} = 5427; # (Actually not a limit)
3521
# The following should be 8192, but is smaller because Frontbase crashes..
3522
$limits{'max_columns'} = 150; # Max number of columns in table
3523
$limits{'max_tables'} = 5000; # 10000 crashed FrontBase
3524
$limits{'max_text_size'} = 65000; # Max size with default buffers.
3525
$limits{'query_size'} = 8000000; # Max size with default buffers.
3526
$limits{'max_index'} = 38; # Max number of keys
3527
$limits{'max_index_parts'} = 20; # Max segments/key
3528
$limits{'max_column_name'} = 128; # max table and column name
3530
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
3531
$limits{'load_data_infile'} = 1; # Has load data infile
3532
$limits{'lock_tables'} = 0; # Has lock tables
3533
$limits{'functions'} = 1; # Has simple functions (+/-)
3534
$limits{'group_functions'} = 1; # Have group functions
3535
$limits{'group_distinct_functions'}= 0; # Have count(distinct)
3536
$limits{'select_without_from'}= 0;
3537
$limits{'multi_drop'} = 0; # Drop table cannot take many tables
3538
$limits{'subqueries'} = 1; # Supports sub-queries.
3539
$limits{'left_outer_join'} = 1; # Supports left outer joins
3540
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
3541
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING
3542
$limits{'having_with_group'} = 0; # Can use group functions in HAVING
3543
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
3544
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
3545
$limits{'group_by_position'} = 0; # Use of 'GROUP BY 1'
3546
$limits{'alter_table'} = 1; # Have ALTER TABLE
3547
$limits{'alter_add_multi_col'}= 0; # Have ALTER TABLE t add a int,add b int;
3548
$limits{'alter_table_dropcol'}= 0; # Have ALTER TABLE DROP column
3549
$limits{'insert_multi_value'} = 1;
3551
$limits{'group_func_extra_std'} = 0; # Does not have group function std().
3553
$limits{'func_odbc_mod'} = 0; # Have function mod.
3554
$limits{'func_extra_%'} = 0; # Does not have % as alias for mod()
3555
$limits{'func_odbc_floor'} = 0; # Has func_odbc_floor function
3556
$limits{'func_extra_if'} = 0; # Does not have function if.
3557
$limits{'column_alias'} = 1; # Alias for fields in select statement.
3558
$limits{'NEG'} = 1; # Supports -id
3559
$limits{'func_extra_in_num'} = 0; # Has function in
3560
$limits{'limit'} = 0; # Does not support the limit attribute
3561
$limits{'insert_select'} = 0;
3562
$limits{'order_by_unused'} = 0;
3564
# We don't get an error for duplicate row in 'test-insert'
3565
$limits{'unique_index'} = 0; # Unique index works or not
3566
# We can't use a blob as a normal string (we got a wierd error)
3567
$limits{'working_blobs'} = 0;
3568
# 'select min(region),max(region) from bench1' kills the server after a while
3569
$limits{'group_func_sql_min_str'} = 0;
3570
# If you do select f1,f2,f3...f200 from table, Frontbase dies.
3571
$limits{'working_all_fields'} = 0;
3572
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
3578
# Get the version number of the database
3584
my ($dbh,$sth,$version,@row);
3586
# $dbh=$self->connect();
3588
# Pick up SQLGetInfo option SQL_DBMS_VER (18)
3590
#$version = $dbh->func(18, GetInfo);
3591
$version="FrontBase 3.3";
3593
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
3598
# Connection with optional disabling of logging
3605
$dbh=DBI->connect($self->{'data_source'},
3607
$main::opt_password,
3609
'fb_host'=>$main::opt_host
3611
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
3612
$db->{AutoCommit}=1;
3613
# $dbh->do("SET OPTION LOG_OFF=1,UPDATE_LOG=0");
3618
# Returns a list of statements to create a table
3619
# The field types are in ANSI SQL format.
3621
# If one uses $main::opt_fast then one is allowed to use
3622
# non standard types to get better speed.
3627
my($self,$table_name,$fields,$index,$options) = @_;
3628
my($query,@queries,@indexes,@keys);
3630
$query="create table $table_name (";
3631
foreach $field (@$fields)
3633
$field =~ s/ blob/ varchar(32000)/i;
3634
$field =~ s/ big_decimal/ float/i;
3635
$field =~ s/ double/ float/i;
3636
$field =~ s/ tinyint/ smallint/i;
3637
$field =~ s/ mediumint/ int/i;
3638
$field =~ s/ integer/ int/i;
3639
$field =~ s/ float\(\d,\d\)/ float/i;
3640
$field =~ s/ smallint\(\d\)/ smallint/i;
3641
$field =~ s/ int\(\d\)/ int/i;
3642
$query.= $field . ',';
3644
foreach $ind (@$index)
3647
if ( $ind =~ /(\bKEY\b)|(\bUNIQUE\b)/i ){
3648
push(@keys,"ALTER TABLE $table_name ADD $ind");
3650
my @fields = split(' ',$ind);
3651
my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
3652
push(@indexes,$query);
3655
substr($query,-1)=")"; # Remove last ',';
3656
$query.=" $options" if (defined($options));
3657
push(@queries,$query,@keys,@indexes);
3662
my($self,$dbname, $file) = @_;
3663
print "insert of an ascii file isn't supported by InterBase\n";
3668
# Do any conversions to the ANSI SQL query so that the database can handle it
3672
my($self,$sql) = @_;
3677
my ($self,$table,$index) = @_;
3678
return "DROP INDEX $index";
3682
# Abort if the server has crashed
3684
# 1 question should be retried
3687
sub abort_if_fatal_error
3689
return 0 if ($DBI::errstr =~ /No raw data handle/);
3693
sub small_rollback_segment
3698
sub reconnect_on_errors
3705
my ($self,$cmd) = @_;
3709
#############################################################################
3710
# Configuration for SAPDB
3711
#############################################################################
3717
my ($type,$host,$database)= @_;
3722
$self->{'cmp_name'} = "sapdb";
3723
$self->{'data_source'} = "DBI:SAP_DB:$database";
3724
$self->{'limits'} = \%limits;
3725
$self->{'blob'} = "LONG"; # *
3726
$self->{'text'} = "LONG"; # *
3727
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
3728
$self->{'drop_attr'} = "";
3729
$self->{'transactions'} = 1; # Transactions enabled *
3730
$self->{'char_null'} = "";
3731
$self->{'numeric_null'} = "";
3733
$limits{'max_conditions'} = 9999; # (Actually not a limit) *
3734
$limits{'max_columns'} = 1023; # Max number of columns in table *
3735
$limits{'max_tables'} = 65000; # Should be big enough * unlimited actually
3736
$limits{'max_text_size'} = 15000; # Max size with default buffers.
3737
$limits{'query_size'} = 64*1024; # Max size with default buffers. *64 kb by default. May be set by system variable
3738
$limits{'max_index'} = 510; # Max number of keys *
3739
$limits{'max_index_parts'} = 16; # Max segments/key *
3740
$limits{'max_column_name'} = 32; # max table and column name *
3742
$limits{'join_optimizer'} = 1; # Can optimize FROM tables *
3743
$limits{'load_data_infile'} = 0; # Has load data infile *
3744
$limits{'lock_tables'} = 1; # Has lock tables
3745
$limits{'functions'} = 1; # Has simple functions (+/-) *
3746
$limits{'group_functions'} = 1; # Have group functions *
3747
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings *
3748
$limits{'group_distinct_functions'}= 1; # Have count(distinct) *
3749
$limits{'select_without_from'}= 0; # Cannot do 'select 1'; *
3750
$limits{'multi_drop'} = 0; # Drop table cannot take many tables *
3751
$limits{'subqueries'} = 1; # Supports sub-queries. *
3752
$limits{'left_outer_join'} = 1; # Supports left outer joins *
3753
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
3754
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING *
3755
$limits{'having_with_group'} = 1; # Can use group functions in HAVING *
3756
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2 *
3757
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1' *
3758
$limits{'group_by_position'} = 0; # Cannot use 'GROUP BY 1' *
3759
$limits{'alter_table'} = 1; # Have ALTER TABLE *
3760
$limits{'alter_add_multi_col'}= 1; # Have ALTER TABLE t add a int,add b int; *
3761
$limits{'alter_table_dropcol'}= 1; # Have ALTER TABLE DROP column *
3762
$limits{'insert_multi_value'} = 0; # INSERT ... values (1,2),(3,4) *
3764
$limits{'group_func_extra_std'} = 0; # Does not have group function std().
3766
$limits{'func_odbc_mod'} = 0; # Have function mod. *
3767
$limits{'func_extra_%'} = 0; # Does not have % as alias for mod() *
3768
$limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function *
3769
$limits{'func_extra_if'} = 0; # Does not have function if. *
3770
$limits{'column_alias'} = 1; # Alias for fields in select statement. *
3771
$limits{'NEG'} = 1; # Supports -id *
3772
$limits{'func_extra_in_num'} = 0; # Has function in *
3773
$limits{'limit'} = 0; # Does not support the limit attribute *
3774
$limits{'working_blobs'} = 1; # If big varchar/blobs works *
3775
$limits{'order_by_unused'} = 1; #
3776
$limits{'working_all_fields'} = 1; #
3777
$limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
3784
# Get the version number of the database
3790
my ($dbh,$sth,$version,@row);
3792
$dbh=$self->connect();
3793
$sth = $dbh->prepare("SELECT KERNEL FROM VERSIONS") or die $DBI::errstr;
3794
$version="SAP DB (unknown)";
3795
if ($sth->execute && (@row = $sth->fetchrow_array)
3796
&& $row[0] =~ /([\d\.]+)/)
3799
$version =~ s/KERNEL/SAP DB/i;
3803
$version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
3808
# Connection with optional disabling of logging
3815
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
3816
$main::opt_password,{ PrintError => 0, AutoCommit => 1}) ||
3817
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
3823
# Returns a list of statements to create a table
3824
# The field types are in ANSI SQL format.
3829
my($self,$table_name,$fields,$index,$options) = @_;
3830
my($query,@queries,$nr);
3834
$query="create table $table_name (";
3835
foreach $field (@$fields)
3837
$field =~ s/\bmediumint\b/int/i;
3838
$field =~ s/\btinyint\b/int/i;
3839
$field =~ s/ int\(\d\)/ int/i;
3840
$field =~ s/BLOB/LONG/i;
3841
$field =~ s/INTEGER\s*\(\d+\)/INTEGER/i;
3842
$field =~ s/SMALLINT\s*\(\d+\)/SMALLINT/i;
3843
$field =~ s/FLOAT\s*\((\d+),\d+\)/FLOAT\($1\)/i;
3844
$field =~ s/DOUBLE/FLOAT\(38\)/i;
3845
$field =~ s/DOUBLE\s+PRECISION/FLOAT\(38\)/i;
3846
$query.= $field . ',';
3849
foreach $ind (@$index)
3851
if ( $ind =~ /\bKEY\b/i ){
3852
push(@keys,"ALTER TABLE $table_name ADD $ind");
3853
} elsif ($ind =~ /^unique.*\(([^\(]*)\)$/i) {
3855
my $query="create unique index ${table_name}_$nr on $table_name ($1)";
3856
push(@index,$query);
3858
my @fields = split(' ',$ind);
3859
my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
3860
push(@index,$query);
3863
substr($query,-1)=")"; # Remove last ',';
3864
$query.=" $options" if (defined($options));
3865
push(@queries,$query);
3866
push(@queries,@keys);
3867
push(@queries,@index);
3872
my($self,$dbname, $file) = @_;
3873
print "insert of an ascii file isn't supported by SAPDB\n";
3878
# Do any conversions to the ANSI SQL query so that the database can handle it
3882
my($self,$sql) = @_;
3887
my ($self,$table,$index) = @_;
3888
return "DROP INDEX $index";
3892
# Abort if the server has crashed
3894
# 1 question should be retried
3897
sub abort_if_fatal_error
3902
sub small_rollback_segment
3907
sub reconnect_on_errors
3914
my ($self,$cmd) = @_;