Commit b3975229 authored by unknown's avatar unknown

add sapdb section into server-cfg, add a lot of new function and tests into crash-me


sql-bench/crash-me.sh:
  - If double double quotes are allowed in identifiers. 
  - Rollback rolls back meta data
  - NULL sort and NULL sort perserve. 
  - remove one check of "serial".   
  - (Column,Table,Named constraints) new test to crash me if the check syntax is 
    only supported by the parser, but not done for real.
  - For all ..USER tests, (like current_user), add an extra test if
    ...USER() is supported.                                   
  - Add tests for constants TRUE and FALSE                     
  - Add test of LIMIT # OFFSET (PostgreSQL syntax) 
  - add test a lot of new functions
sql-bench/server-cfg.sh:
  add sapdb section
parent 962cedf2
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
# as such, and clarify ones such as "mediumint" with comments such as # as such, and clarify ones such as "mediumint" with comments such as
# "3-byte int" or "same as xxx". # "3-byte int" or "same as xxx".
$version="1.58"; $version="1.59";
use DBI; use DBI;
use Getopt::Long; use Getopt::Long;
...@@ -253,6 +253,9 @@ check_and_report("\` as identifier quote",'quote_ident_with_`',[], ...@@ -253,6 +253,9 @@ check_and_report("\` as identifier quote",'quote_ident_with_`',[],
'select `A` from crash_me',[],"1",0); 'select `A` from crash_me',[],"1",0);
check_and_report("[] as identifier quote",'quote_ident_with_[',[], check_and_report("[] as identifier quote",'quote_ident_with_[',[],
'select [A] from crash_me',[],"1",0); 'select [A] from crash_me',[],"1",0);
report('Double "" in identifiers as "','quote_ident_with_dbl_"',
'create table crash_me1 ("abc""d" integer)',
'drop table crash_me1');
report("Column alias","column_alias","select a as ab from crash_me"); report("Column alias","column_alias","select a as ab from crash_me");
report("Table alias","table_alias","select b.a from crash_me as b"); report("Table alias","table_alias","select b.a from crash_me as b");
...@@ -301,6 +304,7 @@ try_and_report("LIMIT number of rows","select_limit", ...@@ -301,6 +304,7 @@ try_and_report("LIMIT number of rows","select_limit",
["with TOP", ["with TOP",
"select TOP 1 * from crash_me"]); "select TOP 1 * from crash_me"]);
report("SELECT with LIMIT #,#","select_limit2", "select * from crash_me limit 1,1"); report("SELECT with LIMIT #,#","select_limit2", "select * from crash_me limit 1,1");
report("SELECT with LIMIT # OFFSET #","select_limit3", "select * from crash_me limit 1 offset 1");
# The following alter table commands MUST be kept together! # The following alter table commands MUST be kept together!
if ($dbh->do("create table crash_q (a integer, b integer,c1 CHAR(10))")) if ($dbh->do("create table crash_q (a integer, b integer,c1 CHAR(10))"))
...@@ -434,6 +438,9 @@ report("hex strings (x'1ace')","hex_strings","select x'1ace' $end_query"); ...@@ -434,6 +438,9 @@ report("hex strings (x'1ace')","hex_strings","select x'1ace' $end_query");
report_result("Value of logical operation (1=1)","logical_value", report_result("Value of logical operation (1=1)","logical_value",
"select (1=1) $end_query"); "select (1=1) $end_query");
report_result("Value of TRUE","value_of_true","select TRUE $end_query");
report_result("Value of FALSE","value_of_false","select FALSE $end_query");
$logical_value= $limits{'logical_value'}; $logical_value= $limits{'logical_value'};
$false=0; $false=0;
...@@ -584,7 +591,7 @@ print "$limits{'query_size'}\n"; ...@@ -584,7 +591,7 @@ print "$limits{'query_size'}\n";
"int not null identity,unique(q)", "int not null identity,unique(q)",
# postgres types # postgres types
"box","bool","circle","polygon","point","line","lseg","path", "box","bool","circle","polygon","point","line","lseg","path",
"interval", "serial", "inet", "cidr", "macaddr", "interval", "inet", "cidr", "macaddr",
# oracle types # oracle types
"varchar2(16)","nvarchar2(16)","number(9,2)","number(9)", "varchar2(16)","nvarchar2(16)","number(9,2)","number(9)",
...@@ -769,7 +776,6 @@ try_and_report("Automatic row id", "automatic_rowid", ...@@ -769,7 +776,6 @@ try_and_report("Automatic row id", "automatic_rowid",
["CURRENT_DATE","current_date","current_date",0,2], ["CURRENT_DATE","current_date","current_date",0,2],
["CURRENT_TIME","current_time","current_time",0,2], ["CURRENT_TIME","current_time","current_time",0,2],
["CURRENT_TIMESTAMP","current_timestamp","current_timestamp",0,2], ["CURRENT_TIMESTAMP","current_timestamp","current_timestamp",0,2],
["CURRENT_USER","current_user","current_user",0,2],
["EXTRACT","extract_sql","extract(minute from timestamp '2000-02-23 18:43:12.987')",43,0], ["EXTRACT","extract_sql","extract(minute from timestamp '2000-02-23 18:43:12.987')",43,0],
["LOCALTIME","localtime","localtime",0,2], ["LOCALTIME","localtime","localtime",0,2],
["LOCALTIMESTAMP","localtimestamp","localtimestamp",0,2], ["LOCALTIMESTAMP","localtimestamp","localtimestamp",0,2],
...@@ -778,11 +784,8 @@ try_and_report("Automatic row id", "automatic_rowid", ...@@ -778,11 +784,8 @@ try_and_report("Automatic row id", "automatic_rowid",
["NULLIF with numbers","nullif_num","NULLIF(NULLIF(1,2),1)",undef(),4], ["NULLIF with numbers","nullif_num","NULLIF(NULLIF(1,2),1)",undef(),4],
["OCTET_LENGTH","octet_length","octet_length('abc')",3,0], ["OCTET_LENGTH","octet_length","octet_length('abc')",3,0],
["POSITION","position","position('ll' in 'hello')",3,0], ["POSITION","position","position('ll' in 'hello')",3,0],
["SESSION_USER","session_user","session_user",0,2],
["SYSTEM_USER","system_user","system_user",0,2],
["TRIM","trim","trim(trailing from trim(LEADING FROM ' abc '))","abc",3], ["TRIM","trim","trim(trailing from trim(LEADING FROM ' abc '))","abc",3],
["UPPER","upper","UPPER('abc')","ABC",1], ["UPPER","upper","UPPER('abc')","ABC",1],
["USER","user","user"],
["concatenation with ||","concat_as_||","'abc' || 'def'","abcdef",1], ["concatenation with ||","concat_as_||","'abc' || 'def'","abcdef",1],
); );
...@@ -960,8 +963,61 @@ try_and_report("Automatic row id", "automatic_rowid", ...@@ -960,8 +963,61 @@ try_and_report("Automatic row id", "automatic_rowid",
["automatic num->string convert","auto_num2string","concat('a',2)","a2",1], ["automatic num->string convert","auto_num2string","concat('a',2)","a2",1],
["automatic string->num convert","auto_string2num","'1'+2",3,0], ["automatic string->num convert","auto_string2num","'1'+2",3,0],
["concatenation with +","concat_as_+","'abc' + 'def'","abcdef",1], ["concatenation with +","concat_as_+","'abc' + 'def'","abcdef",1],
["SUBSTR (2 arg)",'substr2arg',"substr('abcd',2)",'bcd',1], #sapdb func
["SUBSTR (3 arg)",'substr3arg',"substr('abcd',2,2)",'bc',1],
["LFILL (3 arg)",'lfill3arg',"lfill('abcd','.',6)",'..abcd',1],
["RFILL (3 arg)",'rfill3arg',"rfill('abcd','.',6)",'abcd..',1],
["RPAD (4 arg)",'rpad4arg',"rpad('abcd',2,'+-',8)",'abcd+-+-',1],
["LPAD (4 arg)",'rpad4arg',"lpad('abcd',2,'+-',8)",'+-+-abcd',1],
["SAPDB compatible TRIM (1 arg)",'trim1arg',"trim(' abcd ')",'abcd',1],
["SAPDB compatible TRIM (2 arg)",'trim2arg',"trim('..abcd..','.')",'abcd',1],
["LTRIM (2 arg)",'ltrim2arg',"ltrim('..abcd..','.')",'abcd..',1],
["RTRIM (2 arg)",'rtrim2arg',"rtrim('..abcd..','.')",'..abcd',1],
["EXPAND",'expand2arg',"expand('abcd',6)",'abcd ',0],
["REPLACE (2 arg) ",'replace2arg',"replace('AbCd','bC')",'Ad',1],
["MAPCHAR",'mapchar',"mapchar('A')",'Aa',1],
["ALPHA",'alpha',"alpha('A',2)",'AA',1],
["ASCII in string cast",'ascii_string',"ascii('a')",'a',1],
["EBCDIC in string cast",'ebcdic_string',"ebcdic('a')",'a',1],
["TRUNC (1 arg)",'trunc1arg',"trunc(222.6)",222,0],
["NOROUND",'noround',"noround(222.6)",222.6,0],
["FIXED",'fixed',"fixed(222.6666,10,2)",'222.67',0],
["FLOAT",'float',"float(6666.66,4)",6667,0],
["LENGTH",'length',"length(1)",2,0],
["INDEX",'index',"index('abcdefg','cd',1,1)",3,0],
["ADDDATE",'adddate',"ADDDATE('20021201',3)",'20021204',0],
["SUBDATE",'subdate',"SUBDATE('20021204',3)",'20021201',0],
["DATEDIFF (2 arg)",'datediff2arg',"DATEDIFF('20021204','20021201')",'3',0], # sapdb
["DAYOFWEEK with sapdb internal date as arg",'dayofweek_sapdb',"DAYOFWEEK('19630816')",'5',0],
["WEEKOFYEAR",'weekofyear',"WEEKOFYEAR('19630816')",'33',0],
["DAYOFMONTH with sapdb internal date as arg",'dayofmonth_sapdb',"dayofmonth('19630816')",'16',0],
["DAYOFYEAR with sapdb internal date as arg",'dayofyear_sapdb',"DAYOFYEAR('19630816')",'228',0],
["MAKEDATE",'makedate',"MAKEDATE(1963,228)",'19630816',0],
["DAYNAME with sapdb internal date as arg",'dayname_sapdb',"DAYNAME('19630816')",'Friday',0],
["MONTHNAME with sapdb internal date as arg",'monthname_sapdb',"MONTHNAME('19630816')",'August',0],
["ADDTIME",'addtime',"ADDTIME('00200212','00000300')",'00200215',0],
["SUBTIME",'subdate',"SUBDATE('00200215','00000300')",'00200212',0],
["TIMEDIFF",'timediff',"TIMEDIFF('00200215','00200212')",'00000003',0],
["MAKETIME",'maketime',"MAKETIME(20,02,12)",'00200212',0],
["YEAR with sapdb internal date as arg",'year_sapdb',"YEAR('20021201')",'2002',0],
["MONTH with sapdb internal date as arg",'month_sapdb',"MONTH('20021201')",'12',0],
["DAY",'day',"DAY('20021201')",1,0],
["HOUR with sapdb internal time as arg",'hour_sapdb',"HOUR('00200212')",20,0],
["MINUTE with sapdb internal time as arg",'minute_sapdb',"MINUTE('00200212')",2,0],
["SECOND with sapdb internal time as arg",'second_sapdb',"SECOND('00200212')",12,0],
["MICROSECOND",'microsecond',"MICROSECOND('19630816200212111111')",'111111',0],
["TIMESTAMP",'timestamp',"timestamp('19630816','00200212')",'19630816200212000000',0],
["TIME",'time',"time('00200212')",'00200212',0],
["DATE",'date',"date('19630816')",'19630816',0],
["VALUE",'value',"value(NULL,'WALRUS')",'WALRUS',0],
["DECODE",'decode',"DECODE('S-103','T72',1,'S-103',2,'Leopard',3)",2,0],
["NUM",'num',"NUM('2123')",2123,0],
["CHAR (conversation date)",'char_date',"CHAR(DATE('19630816'),EUR)",'16.08.1963',0],
["CHR (any type to string)",'chr_str',"CHR(67)",'67',0],
["HEX",'hex',"HEX('A')",41,0],
); );
@sql_group_functions= @sql_group_functions=
( (
["AVG","avg","avg(a)",1,0], ["AVG","avg","avg(a)",1,0],
...@@ -1131,6 +1187,20 @@ else ...@@ -1131,6 +1187,20 @@ else
} }
if ($limits{'func_extra_noround'} eq 'yes')
{
report("Ignoring NOROUND","ignoring_noround",
"create table crash_q (a int)",
"insert into crash_q values(noround(10.22))",
"drop table crash_q $drop_attr");
}
check_parenthesis("func_sql_","CURRENT_USER");
check_parenthesis("func_sql_","SESSION_USER");
check_parenthesis("func_sql_","SYSTEM_USER");
check_parenthesis("func_sql_","USER");
report("LIKE on numbers","like_with_number", report("LIKE on numbers","like_with_number",
"create table crash_q (a int,b int)", "create table crash_q (a int,b int)",
"insert into crash_q values(10,10)", "insert into crash_q values(10,10)",
...@@ -1561,19 +1631,29 @@ if (!defined($limits{"transactions"})) ...@@ -1561,19 +1631,29 @@ if (!defined($limits{"transactions"}))
{ {
my ($limit,$type); my ($limit,$type);
$limit="transactions"; $limit="transactions";
$limit_r="rollback_metadata";
print "$limit: "; print "$limit: ";
foreach $type (('', 'type=bdb', 'type=innodb', 'type=gemini')) foreach $type (('', 'type=bdb', 'type=innodb', 'type=gemini'))
{ {
undef($limits{$limit}); undef($limits{$limit});
last if (!report_trans($limit, if (!report_trans($limit,
[create_table("crash_q",["a integer not null"],[], [create_table("crash_q",["a integer not null"],[],
$type), $type),
"insert into crash_q values (1)"], "insert into crash_q values (1)"],
"select * from crash_q", "select * from crash_q",
"drop table crash_q $drop_attr" "drop table crash_q $drop_attr"
)); ))
{
report_rollback($limit_r,
[create_table("crash_q",["a integer not null"],[],
$type)],
"insert into crash_q values (1)",
"drop table crash_q $drop_attr" );
last;
};
} }
print "$limits{$limit}\n"; print "$limits{$limit}\n";
print "$limit_r: $limits{$limit_r}\n";
} }
report("atomic updates","atomic_updates", report("atomic updates","atomic_updates",
...@@ -1644,14 +1724,29 @@ report("Column constraints","constraint_check", ...@@ -1644,14 +1724,29 @@ report("Column constraints","constraint_check",
"create table crash_q (a int check (a>0))", "create table crash_q (a int check (a>0))",
"drop table crash_q $drop_attr"); "drop table crash_q $drop_attr");
report("Ignoring column constraints","ignoring_constraint_check",
"create table crash_q (a int check (a>0))",
"insert into crash_q values(0)",
"drop table crash_q $drop_attr") if ($limits{'constraint_check'} eq 'yes');
report("Table constraints","constraint_check_table", report("Table constraints","constraint_check_table",
"create table crash_q (a int ,b int, check (a>b))", "create table crash_q (a int ,b int, check (a>b))",
"drop table crash_q $drop_attr"); "drop table crash_q $drop_attr");
report("Named constraints","constraint_check", report("Ignoring table constraints","ignoring_constraint_check_table",
"create table crash_q (a int ,b int, check (a>b))",
"insert into crash_q values(0,0)",
"drop table crash_q $drop_attr") if ($limits{'constraint_check_table'} eq 'yes');
report("Named constraints","constraint_check_named",
"create table crash_q (a int ,b int, constraint abc check (a>b))", "create table crash_q (a int ,b int, constraint abc check (a>b))",
"drop table crash_q $drop_attr"); "drop table crash_q $drop_attr");
report("Ignoring named constraints","ignoring_constraint_check_named",
"create table crash_q (a int ,b int, constraint abc check (a>b))",
"insert into crash_q values(0,0)",
"drop table crash_q $drop_attr") if ($limits{'constraint_check_named'} eq 'yes');
report("NULL constraint (SyBase style)","constraint_null", report("NULL constraint (SyBase style)","constraint_null",
"create table crash_q (a int null)", "create table crash_q (a int null)",
"drop table crash_q $drop_attr"); "drop table crash_q $drop_attr");
...@@ -2009,6 +2104,90 @@ find_limit("number of columns in group by","columns_in_group_by", ...@@ -2009,6 +2104,90 @@ find_limit("number of columns in group by","columns_in_group_by",
["drop table crash_q $drop_attr"], ["drop table crash_q $drop_attr"],
$max_order_by)); $max_order_by));
# Safe arithmetic test
$prompt="safe decimal arithmetic";
$key="safe_decimal_arithmetic";
if (!defined($limits{$key}))
{
print "$prompt=";
save_incomplete($key,$prompt);
if (!safe_query($server->create("crash_me_a",["a decimal(10,2)","b decimal(10,2)"])))
{
print DBI->errstr();
die "Can't create table 'crash_me_a' $DBI::errstr\n";
};
if (!safe_query(["insert into crash_me_a (a,b) values (11.4,18.9)"]))
{
die "Can't insert into table 'crash_me_a' a record: $DBI::errstr\n";
};
$arithmetic_safe = 'no';
$arithmetic_safe = 'yes'
if ( (safe_query_result('select count(*) from crash_me_a where a+b=30.3',1,0) == 0)
and (safe_query_result('select count(*) from crash_me_a where a+b-30.3 = 0',1,0) == 0)
and (safe_query_result('select count(*) from crash_me_a where a+b-30.3 < 0',0,0) == 0)
and (safe_query_result('select count(*) from crash_me_a where a+b-30.3 > 0',0,0) == 0) );
save_config_data($key,$arithmetic_safe,$prompt);
print "$arithmetic_safe\n";
assert("drop table crash_me_a $drop_attr");
}
else
{
print "$prompt=$limits{$key} (cached)\n";
}
# Check where is null values in sorted recordset
if (!safe_query($server->create("crash_me_n",["i integer","r integer"])))
{
print DBI->errstr();
die "Can't create table 'crash_me_n' $DBI::errstr\n";
};
assert("insert into crash_me_n (i) values(1)");
assert("insert into crash_me_n values(2,2)");
assert("insert into crash_me_n values(3,3)");
assert("insert into crash_me_n values(4,4)");
assert("insert into crash_me_n (i) values(5)");
$key = "position_of_null";
$prompt ="Where is null values in sorted recordset";
if (!defined($limits{$key}))
{
save_incomplete($key,$prompt);
print "$prompt=";
$sth=$dbh->prepare("select r from crash_me_n order by r ");
$sth->execute;
$limit= detect_null_position($sth);
$sth->finish;
print "$limit\n";
save_config_data($key,$limit,$prompt);
} else {
print "$prompt=$limits{$key} (cache)\n";
}
$key = "position_of_null_desc";
$prompt ="Where is null values in sorted recordset (DESC)";
if (!defined($limits{$key}))
{
save_incomplete($key,$prompt);
print "$prompt=";
$sth=$dbh->prepare("select r from crash_me_n order by r desc");
$sth->execute;
$limit= detect_null_position($sth);
$sth->finish;
print "$limit\n";
save_config_data($key,$limit,$prompt);
} else {
print "$prompt=$limits{$key} (cache)\n";
}
assert("drop table crash_me_n $drop_attr");
# #
# End of test # End of test
# #
...@@ -2022,6 +2201,41 @@ $dbh->disconnect || warn $dbh->errstr; ...@@ -2022,6 +2201,41 @@ $dbh->disconnect || warn $dbh->errstr;
save_all_config_data(); save_all_config_data();
exit 0; exit 0;
# Check where is nulls in the sorted result (for)
# it expects exactly 5 rows in the result
sub detect_null_position
{
my $sth = shift;
my ($z,$r1,$r2,$r3,$r4,$r5);
$r1 = $sth->fetchrow_array;
$r2 = $sth->fetchrow_array;
$r3 = $sth->fetchrow_array;
$r4 = $sth->fetchrow_array;
$r5 = $sth->fetchrow_array;
return "first" if ( !defined($r1) && !defined($r2) && defined($r3));
return "last" if ( !defined($r5) && !defined($r4) && defined($r3));
return "random";
}
sub check_parenthesis {
my $prefix=shift;
my $fn=shift;
my $resultat='no';
my $param_name=$prefix.lc($fn);
save_incomplete($param_name,$fn);
if (safe_query("select $fn $end_query") == 1)
{
$resultat="yes";
}
elsif ( safe_query("select $fn() $end_query") == 1)
{
$resultat="with_parenthesis";
}
save_config_data($param_name,$resultat,$fn);
}
sub usage sub usage
{ {
print <<EOF; print <<EOF;
...@@ -2524,10 +2738,10 @@ sub report_result ...@@ -2524,10 +2738,10 @@ sub report_result
{ {
save_incomplete($limit,$prompt); save_incomplete($limit,$prompt);
$error=safe_query_result($query,"1",2); $error=safe_query_result($query,"1",2);
save_config_data($limit,$error ? "not supported" : $last_result,$prompt); save_config_data($limit,$error ? "not supported" :$last_result,$prompt);
} }
print "$limits{$limit}\n"; print "$limits{$limit}\n";
return $limits{$limit} ne "no"; return $limits{$limit} ne "not supported";
} }
sub report_trans sub report_trans
...@@ -2541,17 +2755,12 @@ sub report_trans ...@@ -2541,17 +2755,12 @@ sub report_trans
{ {
if (safe_query(\@$queries)) if (safe_query(\@$queries))
{ {
$rc = $dbh->rollback; $dbh->rollback;
if ($rc) { $dbh->{AutoCommit} = 1;
$dbh->{AutoCommit} = 1;
if (safe_query_result($check,"","")) { if (safe_query_result($check,"","")) {
save_config_data($limit,"yes",$limit); save_config_data($limit,"yes",$limit);
} }
safe_query($clear); safe_query($clear);
} else {
$dbh->{AutoCommit} = 1;
save_config_data($limit,"error",$limit);
}
} else { } else {
save_config_data($limit,"error",$limit); save_config_data($limit,"error",$limit);
} }
...@@ -2566,6 +2775,39 @@ sub report_trans ...@@ -2566,6 +2775,39 @@ sub report_trans
return $limits{$limit} ne "yes"; return $limits{$limit} ne "yes";
} }
sub report_rollback
{
my ($limit,$queries,$check,$clear)=@_;
if (!defined($limits{$limit}))
{
save_incomplete($limit,$prompt);
eval {undef($dbh->{AutoCommit})};
if (!$@)
{
if (safe_query(\@$queries))
{
$dbh->rollback;
$dbh->{AutoCommit} = 1;
if (safe_query($check)) {
save_config_data($limit,"no",$limit);
} else {
save_config_data($limit,"yes",$limit);
};
safe_query($clear);
} else {
save_config_data($limit,"error",$limit);
}
}
else
{
save_config_data($limit,"error",$limit);
}
safe_query($clear);
}
$dbh->{AutoCommit} = 1;
return $limits{$limit} ne "yes";
}
sub check_and_report sub check_and_report
{ {
...@@ -2892,7 +3134,7 @@ sub read_config_data ...@@ -2892,7 +3134,7 @@ sub read_config_data
{ {
if ($key !~ /restart/i) if ($key !~ /restart/i)
{ {
$limits{$key}=$limit; $limits{$key}=$limit eq "null"? undef : $limit;
$prompts{$key}=length($prompt) ? substr($prompt,2) : ""; $prompts{$key}=length($prompt) ? substr($prompt,2) : "";
delete $limits{'restart'}; delete $limits{'restart'};
} }
...@@ -2922,7 +3164,8 @@ sub save_config_data ...@@ -2922,7 +3164,8 @@ sub save_config_data
return if (defined($limits{$key}) && $limits{$key} eq $limit); return if (defined($limits{$key}) && $limits{$key} eq $limit);
if (!defined($limit) || $limit eq "") if (!defined($limit) || $limit eq "")
{ {
die "Undefined limit for $key\n"; # die "Undefined limit for $key\n";
$limit = 'null';
} }
print CONFIG_FILE "$key=$limit\t# $prompt\n"; print CONFIG_FILE "$key=$limit\t# $prompt\n";
$limits{$key}=$limit; $limits{$key}=$limit;
...@@ -3576,5 +3819,6 @@ sub check_query ...@@ -3576,5 +3819,6 @@ sub check_query
} }
### TODO: ### TODO:
# OID test instead of / in addition to _rowid # OID test instead of / in addition to _rowid
...@@ -69,11 +69,13 @@ sub get_server ...@@ -69,11 +69,13 @@ sub get_server
{ $server= new db_db2($host,$database); } { $server= new db_db2($host,$database); }
elsif ($name =~ /Mimer/i) elsif ($name =~ /Mimer/i)
{ $server= new db_Mimer($host,$database); } { $server= new db_Mimer($host,$database); }
elsif ($name =~ /Sapdb/i)
{ $server= new db_sapdb($host,$database); }
elsif ($name =~ /interBase/i) elsif ($name =~ /interBase/i)
{ $server= new db_interbase($host,$database); } { $server= new db_interbase($host,$database); }
else else
{ {
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 or Sybase.\nIf the connection is done trough ODBC the name must end with _ODBC\n"; 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";
} }
if ($name =~ /_ODBC$/i || defined($odbc) && $odbc) if ($name =~ /_ODBC$/i || defined($odbc) && $odbc)
{ {
...@@ -94,7 +96,7 @@ sub get_server ...@@ -94,7 +96,7 @@ sub get_server
sub all_servers sub all_servers
{ {
return ["Access", "Adabas", "DB2", "Empress", "FrontBase", "Oracle", return ["Access", "Adabas", "DB2", "Empress", "FrontBase", "Oracle",
"Informix", "InterBase", "Mimer", "mSQL", "MS-SQL", "MySQL", "Pg", "Informix", "InterBase", "Mimer", "mSQL", "MS-SQL", "MySQL", "Pg","SAPDB",
"Solid", "Sybase"]; "Solid", "Sybase"];
} }
...@@ -116,7 +118,6 @@ sub new ...@@ -116,7 +118,6 @@ sub new
$self->{'data_source'} .= ";mysql_socket=$socket" if($socket); $self->{'data_source'} .= ";mysql_socket=$socket" if($socket);
$self->{'data_source'} .= ";$connect_options" if($connect_options); $self->{'data_source'} .= ";$connect_options" if($connect_options);
$self->{'limits'} = \%limits; $self->{'limits'} = \%limits;
$self->{'smds'} = \%smds;
$self->{'blob'} = "blob"; $self->{'blob'} = "blob";
$self->{'text'} = "text"; $self->{'text'} = "text";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s' $self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
...@@ -178,7 +179,6 @@ sub new ...@@ -178,7 +179,6 @@ sub new
if (defined($main::opt_create_options) && if (defined($main::opt_create_options) &&
$main::opt_create_options =~ /type=innodb/i) $main::opt_create_options =~ /type=innodb/i)
{ {
$limits{'max_text_size'} = 8000; # Limit in Innobase
$self->{'transactions'} = 1; # Transactions enabled $self->{'transactions'} = 1; # Transactions enabled
} }
if (defined($main::opt_create_options) && if (defined($main::opt_create_options) &&
...@@ -3361,4 +3361,211 @@ sub fix_for_insert ...@@ -3361,4 +3361,211 @@ sub fix_for_insert
return $cmd; return $cmd;
} }
#############################################################################
# Configuration for SAPDB
#############################################################################
package db_Sapdb;
sub new
{
my ($type,$host,$database)= @_;
my $self= {};
my %limits;
bless $self;
$self->{'cmp_name'} = "sapdb";
$self->{'data_source'} = "DBI:SAP_DB:$database";
$self->{'limits'} = \%limits;
$self->{'blob'} = "LONG"; # *
$self->{'text'} = "LONG"; # *
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
$self->{'transactions'} = 1; # Transactions enabled *
$self->{'char_null'} = "";
$self->{'numeric_null'} = "";
$limits{'max_conditions'} = 9999; # (Actually not a limit) *
$limits{'max_columns'} = 1023; # Max number of columns in table *
$limits{'max_tables'} = 65000; # Should be big enough * unlimited actually
$limits{'max_text_size'} = 15000; # Max size with default buffers.
$limits{'query_size'} = 64*1024; # Max size with default buffers. *64 kb by default. May be set by system variable
$limits{'max_index'} = 510; # Max number of keys *
$limits{'max_index_parts'} = 16; # Max segments/key *
$limits{'max_column_name'} = 32; # max table and column name *
$limits{'join_optimizer'} = 1; # Can optimize FROM tables *
$limits{'load_data_infile'} = 0; # Has load data infile *
$limits{'lock_tables'} = 1; # Has lock tables
$limits{'functions'} = 1; # Has simple functions (+/-) *
$limits{'group_functions'} = 1; # Have group functions *
$limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings *
$limits{'group_distinct_functions'}= 1; # Have count(distinct) *
$limits{'select_without_from'}= 0; # Cannot do 'select 1'; *
$limits{'multi_drop'} = 0; # Drop table cannot take many tables *
$limits{'subqueries'} = 1; # Supports sub-queries. *
$limits{'left_outer_join'} = 1; # Supports left outer joins *
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
$limits{'having_with_alias'} = 0; # Can use aliases in HAVING *
$limits{'having_with_group'} = 1; # Can use group functions in HAVING *
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2 *
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1' *
$limits{'group_by_position'} = 0; # Cannot use 'GROUP BY 1' *
$limits{'alter_table'} = 1; # Have ALTER TABLE *
$limits{'alter_add_multi_col'}= 1; # Have ALTER TABLE t add a int,add b int; *
$limits{'alter_table_dropcol'}= 1; # Have ALTER TABLE DROP column *
$limits{'insert_multi_value'} = 0; # INSERT ... values (1,2),(3,4) *
$limits{'group_func_extra_std'} = 0; # Does not have group function std().
$limits{'func_odbc_mod'} = 0; # Have function mod. *
$limits{'func_extra_%'} = 0; # Does not have % as alias for mod() *
$limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function *
$limits{'func_extra_if'} = 0; # Does not have function if. *
$limits{'column_alias'} = 1; # Alias for fields in select statement. *
$limits{'NEG'} = 1; # Supports -id *
$limits{'func_extra_in_num'} = 0; # Has function in *
$limits{'limit'} = 0; # Does not support the limit attribute *
$limits{'working_blobs'} = 1; # If big varchar/blobs works *
$limits{'order_by_unused'} = 1; #
$limits{'working_all_fields'} = 1; #
return $self;
}
#
# Get the version number of the database
#
sub version
{
my ($self)=@_;
my ($dbh,$sth,$version,@row);
$dbh=$self->connect();
$sth = $dbh->prepare("SELECT KERNEL FROM VERSIONS") or die $DBI::errstr;
$version="SAP DB (unknown)";
if ($sth->execute && (@row = $sth->fetchrow_array)
&& $row[0] =~ /([\d\.]+)/)
{
$version="sap-db $1";
}
$sth->finish;
$dbh->disconnect;
return $version;
}
#
# Connection with optional disabling of logging
#
sub connect
{
my ($self)=@_;
my ($dbh);
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
$main::opt_password,{ PrintError => 0, AutoCommit => 1}) ||
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
return $dbh;
}
#
# Returns a list of statements to create a table
# The field types are in ANSI SQL format.
#
sub create
{
my($self,$table_name,$fields,$index,$options) = @_;
my($query,@queries,$nr);
my @index;
my @keys;
$query="create table $table_name (";
foreach $field (@$fields)
{
$field =~ s/\bmediumint\b/int/i;
$field =~ s/\btinyint\b/int/i;
$field =~ s/ int\(\d\)/ int/i;
$field =~ s/BLOB/LONG/i;
$field =~ s/INTEGER\s*\(\d+\)/INTEGER/i;
$field =~ s/SMALLINT\s*\(\d+\)/SMALLINT/i;
$field =~ s/FLOAT\s*\((\d+),\d+\)/FLOAT\($1\)/i;
$field =~ s/DOUBLE/FLOAT\(38\)/i;
$field =~ s/DOUBLE\s+PRECISION/FLOAT\(38\)/i;
$query.= $field . ',';
}
$nr=0;
foreach $ind (@$index)
{
if ( $ind =~ /\bKEY\b/i ){
push(@keys,"ALTER TABLE $table_name ADD $ind");
} elsif ($ind =~ /^unique.*\(([^\(]*)\)$/i) {
$nr++;
my $query="create unique index ${table_name}_$nr on $table_name ($1)";
push(@index,$query);
}else{
my @fields = split(' ',$ind);
my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
print "$query \n";
push(@index,$query);
}
}
substr($query,-1)=")"; # Remove last ',';
$query.=" $options" if (defined($options));
push(@queries,$query);
push(@queries,@keys);
push(@queries,@index);
return @queries;
}
sub insert_file {
my($self,$dbname, $file) = @_;
print "insert of an ascii file isn't supported by SAPDB\n";
return 0;
}
#
# Do any conversions to the ANSI SQL query so that the database can handle it
#
sub query {
my($self,$sql) = @_;
return $sql;
}
sub drop_index {
my ($self,$table,$index) = @_;
return "DROP INDEX $index";
}
#
# Abort if the server has crashed
# return: 0 if ok
# 1 question should be retried
#
sub abort_if_fatal_error
{
return 0;
}
sub small_rollback_segment
{
return 0;
}
sub reconnect_on_errors
{
return 0;
}
sub fix_for_insert
{
my ($self,$cmd) = @_;
return $cmd;
}
1; 1;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment