Merge OQGraph into MariaDB 5.2.

(and in the process, fix compile-bintar to link C++ with g++ rather than gcc).
This commit is contained in:
unknown 2010-03-31 10:17:03 +02:00
commit 7f110d15b1
73 changed files with 3813 additions and 361 deletions

View file

@ -204,7 +204,7 @@ if test -z "$CC" ; then
fi fi
if test -z "$CXX" ; then if test -z "$CXX" ; then
CXX=gcc CXX=g++
fi fi
# If ccache (a compiler cache which reduces build time) # If ccache (a compiler cache which reduces build time)

View file

@ -32,8 +32,7 @@
# .so files at runtime (either system stuff like NSS, or server # .so files at runtime (either system stuff like NSS, or server
# plugins). # plugins).
# #
# We link libgcc statically (and avoid linking libstdc++ at all by # We link libgcc statically to avoid reduce nasty library version dependencies.
# CXX=gcc), to avoid reduce nasty library version dependencies.
test -f Makefile && make distclean test -f Makefile && make distclean
@ -52,13 +51,12 @@ get_cpuopt
get_make_parallel_flag get_make_parallel_flag
# Use gcc rather than g++ to avoid linking libstdc++.so (which we don't need). # Use gcc rather than g++ to avoid linking libstdc++.so (which we don't need).
COMP="gcc -static-libgcc"
FLAGS="-O2 -fno-omit-frame-pointer -g -pipe -Wall $CPUOPT" FLAGS="-O2 -fno-omit-frame-pointer -g -pipe -Wall $CPUOPT"
# Don't press on in case of error. # Don't press on in case of error.
set -e set -e
CC="$COMP" CXX="$COMP" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \ CC="gcc -static-libgcc" CXX="g++ -static-libgcc" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \
./configure \ ./configure \
--prefix=/usr/local/mysql \ --prefix=/usr/local/mysql \
--exec-prefix=/usr/local/mysql \ --exec-prefix=/usr/local/mysql \

View file

@ -660,7 +660,7 @@ static ha_checksum checksum_format_specifier(const char* msg)
case 'u': case 'u':
case 'x': case 'x':
case 's': case 's':
chksum= my_checksum(chksum, start, (uint) (p + 1 - start)); chksum= my_checksum(chksum, (uchar*) start, (uint) (p + 1 - start));
start= 0; /* Not in format specifier anymore */ start= 0; /* Not in format specifier anymore */
break; break;

View file

@ -144,7 +144,7 @@ kq_init(struct event_base *base)
*/ */
if (kevent(kq, if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 || kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
kqueueop->events[0].ident != -1 || ((int) kqueueop->events[0].ident) != -1 ||
kqueueop->events[0].flags != EV_ERROR) { kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue; not using.", __func__); event_warn("%s: detected broken kqueue; not using.", __func__);
free(kqueueop->changes); free(kqueueop->changes);

View file

@ -104,6 +104,7 @@ TEST_DIRS = t r include std_data std_data/parts collections \
suite/pbxt/t suite/pbxt/r \ suite/pbxt/t suite/pbxt/r \
suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \ suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \
suite/vcol suite/vcol/t suite/vcol/r suite/vcol/inc suite/vcol suite/vcol/t suite/vcol/r suite/vcol/inc
suite/oqgraph suite/oqgraph/t suite/oqgraph/r suite/oqgraph/include
# Used by dist-hook and install-data-local to copy all # Used by dist-hook and install-data-local to copy all
# test files into either dist or install directory # test files into either dist or install directory

View file

@ -157,3 +157,4 @@ INSERT INTO t1 VALUES (1);
DROP TEMPORARY TABLE t1; DROP TEMPORARY TABLE t1;
--sync_slave_with_master

View file

@ -2,7 +2,7 @@
[mysqld] [mysqld]
open-files-limit= 1024 open-files-limit= 1024
local-infile local-infile
default-character-set= latin1 character-set-server= latin1
# Increase default connect_timeout to avoid intermittent # Increase default connect_timeout to avoid intermittent
# disconnects when test servers are put under load see BUG#28359 # disconnects when test servers are put under load see BUG#28359

View file

@ -159,7 +159,7 @@ int main(int argc, char* const argv[] )
signal(SIGCHLD, handle_signal); signal(SIGCHLD, handle_signal);
signal(SIGABRT, handle_abort); signal(SIGABRT, handle_abort);
sprintf(safe_process_name, "safe_process[%d]", own_pid); sprintf(safe_process_name, "safe_process[%d]", (int) own_pid);
message("Started"); message("Started");

View file

@ -681,6 +681,8 @@ sub optimize_cases {
if ( $default_engine =~ /^ndb/i ); if ( $default_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1 $tinfo->{'innodb_test'}= 1
if ( $default_engine =~ /^innodb/i ); if ( $default_engine =~ /^innodb/i );
$tinfo->{'pbxt_test'}= 1
if ( $default_engine =~ /^pbxt/i );
} }
} }
@ -778,6 +780,8 @@ sub collect_one_test_case {
my $disabled= shift; my $disabled= shift;
my $suite_opts= shift; my $suite_opts= shift;
my $local_default_storage_engine= $default_storage_engine;
#print "collect_one_test_case\n"; #print "collect_one_test_case\n";
#print " suitedir: $suitedir\n"; #print " suitedir: $suitedir\n";
#print " testdir: $testdir\n"; #print " testdir: $testdir\n";
@ -932,15 +936,26 @@ sub collect_one_test_case {
tags_from_test_file($tinfo,"$testdir/${tname}.test"); tags_from_test_file($tinfo,"$testdir/${tname}.test");
if ( defined $default_storage_engine ) # Get default storage engine from suite.opt file
if (defined $suite_opts &&
"@$suite_opts" =~ "default-storage-engine=\s*([^\s]*)")
{
$local_default_storage_engine= $1;
}
if ( defined $local_default_storage_engine )
{ {
# Different default engine is used # Different default engine is used
# tag test to require that engine # tag test to require that engine
$tinfo->{'ndb_test'}= 1 $tinfo->{'ndb_test'}= 1
if ( $default_storage_engine =~ /^ndb/i ); if ( $local_default_storage_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1 $tinfo->{'innodb_test'}= 1
if ( $default_storage_engine =~ /^innodb/i ); if ( $local_default_storage_engine =~ /^innodb/i );
$tinfo->{'pbxt_test'}= 1
if ( $local_default_storage_engine =~ /^pbxt/i );
} }
@ -1103,6 +1118,28 @@ sub collect_one_test_case {
$tinfo->{template_path}= $config; $tinfo->{template_path}= $config;
} }
if ( $tinfo->{'pbxt_test'} )
{
# This is a test that needs pbxt
if ( $::mysqld_variables{'pbxt'} eq "OFF" ||
! exists $::mysqld_variables{'pbxt'} )
{
# Engine is not supported, skip it
$tinfo->{'skip'}= 1;
return $tinfo;
}
}
else
{
# Only disable engine if it's on by default (to avoid warnings about
# not existing loose options
if ( $::mysqld_variables{'pbxt'} eq "ON")
{
push(@{$tinfo->{'master_opt'}}, "--loose-skip-pbxt");
push(@{$tinfo->{'slave_opt'}}, "--loose-skip-pbxt");
}
}
if ( $tinfo->{'example_plugin_test'} ) if ( $tinfo->{'example_plugin_test'} )
{ {
if ( !$ENV{'EXAMPLE_PLUGIN'} ) if ( !$ENV{'EXAMPLE_PLUGIN'} )
@ -1113,6 +1150,16 @@ sub collect_one_test_case {
} }
} }
if ( $tinfo->{'oqgraph_test'} )
{
if ( !$ENV{'OQGRAPH_PLUGIN'} )
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "Test requires the OQGraph storage engine";
return $tinfo;
}
}
# Set extra config file to use # Set extra config file to use
if (defined $defaults_extra_file) { if (defined $defaults_extra_file) {
@ -1156,6 +1203,7 @@ my @tags=
["include/have_log_bin.inc", "need_binlog", 1], ["include/have_log_bin.inc", "need_binlog", 1],
["include/have_innodb.inc", "innodb_test", 1], ["include/have_innodb.inc", "innodb_test", 1],
["include/have_pbxt.inc", "pbxt_test", 1],
["include/big_test.inc", "big_test", 1], ["include/big_test.inc", "big_test", 1],
["include/have_debug.inc", "need_debug", 1], ["include/have_debug.inc", "need_debug", 1],
["include/have_ndb.inc", "ndb_test", 1], ["include/have_ndb.inc", "ndb_test", 1],
@ -1167,6 +1215,7 @@ my @tags=
["include/not_embedded.inc", "not_embedded", 1], ["include/not_embedded.inc", "not_embedded", 1],
["include/not_valgrind.inc", "not_valgrind", 1], ["include/not_valgrind.inc", "not_valgrind", 1],
["include/have_example_plugin.inc", "example_plugin_test", 1], ["include/have_example_plugin.inc", "example_plugin_test", 1],
["include/have_oqgraph_engine.inc", "oqgraph_test", 1],
["include/have_ssl.inc", "need_ssl", 1], ["include/have_ssl.inc", "need_ssl", 1],
); );

View file

@ -3965,7 +3965,7 @@ sub mysqld_arguments ($$$$) {
} }
} }
mtr_add_arg($args, "%s--default-character-set=latin1", $prefix); mtr_add_arg($args, "%s--character-set-server-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language); mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix); mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);

View file

@ -126,7 +126,7 @@ my $path_config_file; # The generated config file, var/my.cnf
# executables will be used by the test suite. # executables will be used by the test suite.
our $opt_vs_config = $ENV{'MTR_VS_CONFIG'}; our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts,vcol"; my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts,vcol,oqgraph";
my $opt_suites; my $opt_suites;
our $opt_verbose= 0; # Verbose output, enable with --verbose our $opt_verbose= 0; # Verbose output, enable with --verbose
@ -1909,6 +1909,33 @@ sub detect_plugins {
$ENV{'HA_EXAMPLE_SO'}="'".$plugin_filename."'"; $ENV{'HA_EXAMPLE_SO'}="'".$plugin_filename."'";
$ENV{'EXAMPLE_PLUGIN_LOAD'}="--plugin_load=EXAMPLE=".$plugin_filename; $ENV{'EXAMPLE_PLUGIN_LOAD'}="--plugin_load=EXAMPLE=".$plugin_filename;
} }
# --------------------------------------------------------------------------
# Add the path where mysqld will find graph_engine.so
# --------------------------------------------------------------------------
if ($mysql_version_id >= 50100 && !(IS_WINDOWS && $opt_embedded_server)) {
my $plugin_filename;
if (IS_WINDOWS)
{
$plugin_filename = "oqgraph_engine.dll";
}
else
{
$plugin_filename = "oqgraph_engine.so";
}
my $lib_oqgraph_plugin=
mtr_file_exists(vs_config_dirs('storage/oqgraph',$plugin_filename),
"$basedir/storage/oqgraph/.libs/".$plugin_filename,
"$basedir/lib/mariadb/plugin/".$plugin_filename,
"$basedir/lib/mysql/plugin/".$plugin_filename);
$ENV{'OQGRAPH_PLUGIN'}=
($lib_oqgraph_plugin ? basename($lib_oqgraph_plugin) : "");
$ENV{'OQGRAPH_PLUGIN_OPT'}= "--plugin-dir=".
($lib_oqgraph_plugin ? dirname($lib_oqgraph_plugin) : "");
$ENV{'GRAPH_ENGINE_SO'}="'".$plugin_filename."'";
$ENV{'OQGRAPH_PLUGIN_LOAD'}="--plugin_load=;OQGRAPH=".$plugin_filename.";";
}
} }
# #

View file

@ -0,0 +1,4 @@
disable_query_log;
--require r/true.require
select (PLUGIN_LIBRARY LIKE 'oqgraph_engine%') as `TRUE` from information_schema.plugins where PLUGIN_NAME='OQGRAPH';
enable_query_log;

View file

@ -0,0 +1,63 @@
drop table if exists graph;
Warnings:
Note 1051 Unknown table 'graph'
CREATE TABLE graph (
latch SMALLINT UNSIGNED NULL,
origid BIGINT UNSIGNED NULL,
destid BIGINT UNSIGNED NULL,
weight DOUBLE NULL,
seq BIGINT UNSIGNED NULL,
linkid BIGINT UNSIGNED NULL,
KEY (latch, origid, destid) USING HASH,
KEY (latch, destid, origid) USING HASH
) ENGINE=OQGRAPH;
delete from graph;
insert into graph(origid, destid) values (1,2), (2,1);
insert into graph(origid, destid) values (1,3), (3,1);
insert into graph(origid, destid) values (3,4), (4,3);
insert into graph(origid, destid) values (3,5), (5,3);
insert into graph(origid, destid) values (5,6), (6,5);
select * from graph where latch = 2 and origid = 1 and weight = 1;
latch origid destid weight seq linkid
2 1 NULL 1 3 3
2 1 NULL 1 2 2
select * from graph where latch = 2 and origid = 1 and weight = 2;
latch origid destid weight seq linkid
2 1 NULL 2 5 5
2 1 NULL 2 4 4
select * from graph
where latch = 2 and origid = 1 and (weight = 1 or weight = 2);
latch origid destid weight seq linkid
2 1 NULL 2 5 5
2 1 NULL 2 4 4
2 1 NULL 1 3 3
2 1 NULL 1 2 2
select * from graph where latch=1 and origid=1 and destid=6;
latch origid destid weight seq linkid
1 1 6 NULL 0 1
1 1 6 1 1 3
1 1 6 1 2 5
1 1 6 1 3 6
select * from graph where latch=1 and origid=1 and destid=4;
latch origid destid weight seq linkid
1 1 4 NULL 0 1
1 1 4 1 1 3
1 1 4 1 2 4
select * from graph where latch=1 and origid=4 and destid=1;
latch origid destid weight seq linkid
1 4 1 NULL 0 4
1 4 1 1 1 3
1 4 1 1 2 1
insert into graph (origid,destid) values (4,6);
delete from graph where origid=5;
delete from graph where origid=3 and destid=5;
select * from graph where latch=1 and origid=1 and destid=6;
latch origid destid weight seq linkid
1 1 6 NULL 0 1
1 1 6 1 1 3
1 1 6 1 2 4
1 1 6 1 3 6
select * from graph where latch=1 and origid=6 and destid=1;
latch origid destid weight seq linkid
truncate table graph;
drop table graph;

View file

@ -0,0 +1,2 @@
$OQGRAPH_PLUGIN_OPT
$OQGRAPH_PLUGIN_LOAD

View file

@ -0,0 +1,45 @@
-- source suite/oqgraph/include/have_oqgraph_engine.inc
drop table if exists graph;
CREATE TABLE graph (
latch SMALLINT UNSIGNED NULL,
origid BIGINT UNSIGNED NULL,
destid BIGINT UNSIGNED NULL,
weight DOUBLE NULL,
seq BIGINT UNSIGNED NULL,
linkid BIGINT UNSIGNED NULL,
KEY (latch, origid, destid) USING HASH,
KEY (latch, destid, origid) USING HASH
) ENGINE=OQGRAPH;
delete from graph;
insert into graph(origid, destid) values (1,2), (2,1);
insert into graph(origid, destid) values (1,3), (3,1);
insert into graph(origid, destid) values (3,4), (4,3);
insert into graph(origid, destid) values (3,5), (5,3);
insert into graph(origid, destid) values (5,6), (6,5);
select * from graph where latch = 2 and origid = 1 and weight = 1;
select * from graph where latch = 2 and origid = 1 and weight = 2;
select * from graph
where latch = 2 and origid = 1 and (weight = 1 or weight = 2);
select * from graph where latch=1 and origid=1 and destid=6;
select * from graph where latch=1 and origid=1 and destid=4;
select * from graph where latch=1 and origid=4 and destid=1;
insert into graph (origid,destid) values (4,6);
delete from graph where origid=5;
delete from graph where origid=3 and destid=5;
select * from graph where latch=1 and origid=1 and destid=6;
select * from graph where latch=1 and origid=6 and destid=1;
truncate table graph;
drop table graph;

View file

@ -1,6 +1,7 @@
--source include/have_partition.inc --source include/have_partition.inc
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/master-slave.inc --source include/master-slave.inc
--source include/big_test.inc
--vertical_results --vertical_results

View file

@ -0,0 +1,18 @@
drop table if exists t1, t2;
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
BEGIN;
SELECT @@log_bin;
@@log_bin
0
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
COMMIT;
select * from t1;
a
1
select * from t2;
b
2
drop table t1, t2;
drop database pbxt;

View file

@ -0,0 +1,23 @@
-- source include/have_innodb.inc
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
#
# bug lp:544173, xa crash with two 2pc-capable storage engines without binlog
#
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
BEGIN;
# verify that binlog is off
SELECT @@log_bin;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
COMMIT;
select * from t1;
select * from t2;
drop table t1, t2;
drop database pbxt;

View file

@ -0,0 +1 @@
--default-storage-engine=pbxt

View file

@ -165,10 +165,9 @@ USE test;
DROP FUNCTION bug42217_db.upgrade_del_func; DROP FUNCTION bug42217_db.upgrade_del_func;
DROP FUNCTION bug42217_db.upgrade_alter_func; DROP FUNCTION bug42217_db.upgrade_alter_func;
DROP DATABASE bug42217_db; DROP DATABASE bug42217_db;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
stop slave;
DROP USER 'create_rout_db'@'localhost'; DROP USER 'create_rout_db'@'localhost';
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
USE mtr;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
######## BUG#49119 ####### ######## BUG#49119 #######
### i) test case from the 'how to repeat section' ### i) test case from the 'how to repeat section'
stop slave; stop slave;

View file

@ -209,12 +209,18 @@ USE test;
DROP FUNCTION bug42217_db.upgrade_del_func; DROP FUNCTION bug42217_db.upgrade_del_func;
DROP FUNCTION bug42217_db.upgrade_alter_func; DROP FUNCTION bug42217_db.upgrade_alter_func;
DROP DATABASE bug42217_db; DROP DATABASE bug42217_db;
DROP USER 'create_rout_db'@'localhost';
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396"); call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
sync_slave_with_master;
# Drop the user that was already dropped on the slave
connection slave; connection slave;
USE mtr; --disable_warnings
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396"); stop slave;
connection master;
DROP USER 'create_rout_db'@'localhost';
--enable_warnings
# BUG#49119: Master crashes when executing 'REVOKE ... ON # BUG#49119: Master crashes when executing 'REVOKE ... ON
# {PROCEDURE|FUNCTION} FROM ...' # {PROCEDURE|FUNCTION} FROM ...'

View file

@ -45,3 +45,4 @@ select * from t1 order by id;
connection master; connection master;
drop table t1; drop table t1;
drop procedure test_procedure; drop procedure test_procedure;
--sync_slave_with_master

View file

@ -53,6 +53,7 @@ UPDATE t1 SET a=99 WHERE a = 0;
SHOW BINLOG EVENTS; SHOW BINLOG EVENTS;
DROP TABLE t1; DROP TABLE t1;
--sync_slave_with_master
# BUG#17620: Replicate (Row Based) Fails when Query Cache enabled on # BUG#17620: Replicate (Row Based) Fails when Query Cache enabled on
# slave # slave

View file

@ -149,6 +149,8 @@ DROP TABLE IF EXISTS test.t2;
DROP TABLE IF EXISTS test.t3; DROP TABLE IF EXISTS test.t3;
--enable_warnings --enable_warnings
sync_slave_with_master;
diff_files $MYSQLTEST_VARDIR/tmp/trg003_master.sql $MYSQLTEST_VARDIR/tmp/trg003_slave.sql; diff_files $MYSQLTEST_VARDIR/tmp/trg003_master.sql $MYSQLTEST_VARDIR/tmp/trg003_slave.sql;
# End of 5.0 test case # End of 5.0 test case

View file

@ -1 +1 @@
--default-character-set=utf8 --skip-character-set-client-handshake --character-set-server=utf8 --skip-character-set-client-handshake

View file

@ -1 +1 @@
--default-character-set=latin1 --default-collation=latin1_german2_ci --character-set-server=latin1 --default-collation=latin1_german2_ci

View file

@ -1 +1 @@
--default-collation=ucs2_unicode_ci --default-character-set=ucs2,latin1 --default-collation=ucs2_unicode_ci --character-set-server=ucs2,latin1

View file

@ -3924,6 +3924,12 @@ restart:
uint next_status; uint next_status;
uint hash_requests; uint hash_requests;
LINT_INIT(next_hash_link);
LINT_INIT(next_diskpos);
LINT_INIT(next_file);
LINT_INIT(next_status);
LINT_INIT(hash_requests);
total_found++; total_found++;
found++; found++;
KEYCACHE_DBUG_ASSERT(found <= keycache->blocks_used); KEYCACHE_DBUG_ASSERT(found <= keycache->blocks_used);

View file

@ -91,9 +91,12 @@ extern pthread_mutex_t LOCK_gethostbyname_r;
is finished with the structure. is finished with the structure.
*/ */
struct hostent *my_gethostbyname_r(const char *name, struct hostent *
struct hostent *result, char *buffer, my_gethostbyname_r(const char *name,
int buflen, int *h_errnop) struct hostent *result __attribute__((unused)),
char *buffer __attribute__((unused)),
int buflen__attribute__((unused)),
int *h_errnop)
{ {
struct hostent *hp; struct hostent *hp;
pthread_mutex_lock(&LOCK_gethostbyname_r); pthread_mutex_lock(&LOCK_gethostbyname_r);

View file

@ -4252,7 +4252,7 @@ int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
*/ */
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p) int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{ {
int result; int result= 0;
DBUG_ENTER("handler::read_multi_range_next"); DBUG_ENTER("handler::read_multi_range_next");
/* We should not be called after the last call returned EOF. */ /* We should not be called after the last call returned EOF. */

View file

@ -7040,7 +7040,7 @@ bool Item_cache_int::cache_value()
} }
void Item_cache_int::store(Item *item, longlong val_arg) void Item_cache_int::store_longlong(Item *item, longlong val_arg)
{ {
/* An explicit values is given, save it. */ /* An explicit values is given, save it. */
value_cached= TRUE; value_cached= TRUE;

View file

@ -1132,7 +1132,8 @@ class Field_enumerator
{ {
public: public:
virtual void visit_field(Field *field)= 0; virtual void visit_field(Field *field)= 0;
virtual ~Field_enumerator() {}; /* purecov: inspected */ virtual ~Field_enumerator() {}; /* purecov: inspected */
Field_enumerator() {} /* Remove gcc warning */
}; };
@ -3148,7 +3149,7 @@ public:
Item_cache_int(enum_field_types field_type_arg): Item_cache_int(enum_field_types field_type_arg):
Item_cache(field_type_arg), value(0) {} Item_cache(field_type_arg), value(0) {}
void store(Item *item, longlong val_arg); void store_longlong(Item *item, longlong val_arg);
double val_real(); double val_real();
longlong val_int(); longlong val_int();
String* val_str(String *str); String* val_str(String *str);

View file

@ -879,7 +879,7 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item_cache_int *cache= new Item_cache_int(); Item_cache_int *cache= new Item_cache_int();
/* Mark the cache as non-const to prevent re-caching. */ /* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1); cache->set_used_tables(1);
cache->store(item, value); cache->store_longlong(item, value);
*cache_arg= cache; *cache_arg= cache;
*item_arg= cache_arg; *item_arg= cache_arg;
} }
@ -917,13 +917,13 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
cache->set_used_tables(1); cache->set_used_tables(1);
if (!(*a)->is_datetime()) if (!(*a)->is_datetime())
{ {
cache->store((*a), const_value); cache->store_longlong((*a), const_value);
a_cache= cache; a_cache= cache;
a= (Item **)&a_cache; a= (Item **)&a_cache;
} }
else else
{ {
cache->store((*b), const_value); cache->store_longlong((*b), const_value);
b_cache= cache; b_cache= cache;
b= (Item **)&b_cache; b= (Item **)&b_cache;
} }
@ -1145,7 +1145,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME); Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
/* Mark the cache as non-const to prevent re-caching. */ /* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1); cache->set_used_tables(1);
cache->store(item, value); cache->store_longlong(item, value);
*cache_arg= cache; *cache_arg= cache;
*item_arg= cache_arg; *item_arg= cache_arg;
} }

File diff suppressed because it is too large Load diff

View file

@ -91,8 +91,9 @@ public:
@param item_list The list of arguments to the function, can be NULL @param item_list The list of arguments to the function, can be NULL
@return An item representing the parsed function call @return An item representing the parsed function call
*/ */
virtual Item* create(THD *thd, LEX_STRING db, LEX_STRING name, virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
bool use_explicit_name, List<Item> *item_list) = 0; bool use_explicit_name,
List<Item> *item_list) = 0;
protected: protected:
/** Constructor. */ /** Constructor. */

View file

@ -642,7 +642,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
}; };
setup(args[0], NULL); setup_item(args[0], NULL);
/* MIN/MAX can return NULL for empty set indepedent of the used column */ /* MIN/MAX can return NULL for empty set indepedent of the used column */
maybe_null= 1; maybe_null= 1;
unsigned_flag=item->unsigned_flag; unsigned_flag=item->unsigned_flag;
@ -676,7 +676,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
of the original MIN/MAX object and it is saved in this object's cache. of the original MIN/MAX object and it is saved in this object's cache.
*/ */
void Item_sum_hybrid::setup(Item *item, Item *value_arg) void Item_sum_hybrid::setup_item(Item *item, Item *value_arg)
{ {
value= Item_cache::get_cache(item); value= Item_cache::get_cache(item);
value->setup(item); value->setup(item);
@ -1646,7 +1646,7 @@ void Item_sum_hybrid::no_rows_in_result()
Item *Item_sum_min::copy_or_same(THD* thd) Item *Item_sum_min::copy_or_same(THD* thd)
{ {
Item_sum_min *item= new (thd->mem_root) Item_sum_min(thd, this); Item_sum_min *item= new (thd->mem_root) Item_sum_min(thd, this);
item->setup(args[0], value); item->setup_item(args[0], value);
return item; return item;
} }
@ -1669,7 +1669,7 @@ bool Item_sum_min::add()
Item *Item_sum_max::copy_or_same(THD* thd) Item *Item_sum_max::copy_or_same(THD* thd)
{ {
Item_sum_max *item= new (thd->mem_root) Item_sum_max(thd, this); Item_sum_max *item= new (thd->mem_root) Item_sum_max(thd, this);
item->setup(args[0], value); item->setup_item(args[0], value);
return item; return item;
} }

View file

@ -870,7 +870,7 @@ protected:
was_values(item->was_values) was_values(item->was_values)
{ } { }
bool fix_fields(THD *, Item **); bool fix_fields(THD *, Item **);
void setup(Item *item, Item *value_arg); void setup_item(Item *item, Item *value_arg);
void clear(); void clear();
double val_real(); double val_real();
longlong val_int(); longlong val_int();

View file

@ -5424,7 +5424,7 @@ int TC_LOG_MMAP::open(const char *opt_name)
pg->state=POOL; pg->state=POOL;
pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST);
pthread_cond_init (&pg->cond, 0); pthread_cond_init (&pg->cond, 0);
pg->start=(my_xid *)(data + i*tc_log_page_size); pg->ptr= pg->start=(my_xid *)(data + i*tc_log_page_size);
pg->size=pg->free=tc_log_page_size/sizeof(my_xid); pg->size=pg->free=tc_log_page_size/sizeof(my_xid);
pg->end=pg->start + pg->size; pg->end=pg->start + pg->size;
} }
@ -5659,7 +5659,15 @@ int TC_LOG_MMAP::sync()
/* marking 'syncing' slot free */ /* marking 'syncing' slot free */
pthread_mutex_lock(&LOCK_sync); pthread_mutex_lock(&LOCK_sync);
syncing=0; syncing=0;
pthread_cond_signal(&active->cond); // wake up a new syncer /*
we check the "active" pointer without LOCK_active. Still, it's safe -
"active" can change from NULL to not NULL any time, but it
will take LOCK_sync before waiting on active->cond. That is, it can never
miss a signal.
And "active" can change to NULL only after LOCK_sync, so this is safe too.
*/
if (active)
pthread_cond_signal(&active->cond); // wake up a new syncer
pthread_mutex_unlock(&LOCK_sync); pthread_mutex_unlock(&LOCK_sync);
return err; return err;
} }

View file

@ -8371,6 +8371,8 @@ mysqld_get_one_option(int optid,
case (int) OPT_INIT_RPL_ROLE: case (int) OPT_INIT_RPL_ROLE:
{ {
int role; int role;
LINT_INIT(role);
if (!find_opt_type(argument, &rpl_role_typelib, opt->name, &role)) if (!find_opt_type(argument, &rpl_role_typelib, opt->name, &role))
{ {
rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE; rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
@ -8427,6 +8429,8 @@ mysqld_get_one_option(int optid,
case OPT_BINLOG_FORMAT: case OPT_BINLOG_FORMAT:
{ {
int id; int id;
LINT_INIT(id);
if (!find_opt_type(argument, &binlog_format_typelib, opt->name, &id)) if (!find_opt_type(argument, &binlog_format_typelib, opt->name, &id))
{ {
global_system_variables.binlog_format= opt_binlog_format_id= id - 1; global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
@ -8677,6 +8681,8 @@ mysqld_get_one_option(int optid,
else else
{ {
int type; int type;
LINT_INIT(type);
if (!find_opt_type(argument, &delay_key_write_typelib, opt->name, &type)) if (!find_opt_type(argument, &delay_key_write_typelib, opt->name, &type))
delay_key_write_options= (uint) type-1; delay_key_write_options= (uint) type-1;
} }
@ -8688,6 +8694,8 @@ mysqld_get_one_option(int optid,
case OPT_TX_ISOLATION: case OPT_TX_ISOLATION:
{ {
int type; int type;
LINT_INIT(type);
if (!find_opt_type(argument, &tx_isolation_typelib, opt->name, &type)) if (!find_opt_type(argument, &tx_isolation_typelib, opt->name, &type))
global_system_variables.tx_isolation= (type-1); global_system_variables.tx_isolation= (type-1);
break; break;
@ -8775,6 +8783,7 @@ mysqld_get_one_option(int optid,
ulong method_conv; ulong method_conv;
int method; int method;
LINT_INIT(method_conv); LINT_INIT(method_conv);
LINT_INIT(method);
myisam_stats_method_str= argument; myisam_stats_method_str= argument;
if (!find_opt_type(argument, &myisam_stats_method_typelib, if (!find_opt_type(argument, &myisam_stats_method_typelib,
@ -8837,6 +8846,7 @@ mysqld_get_one_option(int optid,
case OPT_THREAD_HANDLING: case OPT_THREAD_HANDLING:
{ {
int id; int id;
LINT_INIT(id);
if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id)) if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id))
global_system_variables.thread_handling= id - 1; global_system_variables.thread_handling= id - 1;
opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling]; opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling];

View file

@ -279,7 +279,7 @@ static int net_data_is_ready(my_socket sd)
@param clear_buffer if <> 0, then clear all data from comm buff @param clear_buffer if <> 0, then clear all data from comm buff
*/ */
void net_clear(NET *net, my_bool clear_buffer) void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{ {
#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF) #if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
size_t count; size_t count;

View file

@ -1266,16 +1266,16 @@ uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type,
void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type) void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
{ {
slave_exec_mode_options= 0; slave_exec_mode_options= (ULL(1) << SLAVE_EXEC_MODE_STRICT);
bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
} }
bool sys_var_set_slave_mode::check(THD *thd, set_var *var) bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
{ {
bool rc= sys_var_set::check(thd, var); bool rc= sys_var_set::check(thd, var);
if (!rc && if (!rc &&
bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 && test_all_bits(var->save_result.ulong_value,
bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
(ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{ {
rc= true; rc= true;
my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), ""); my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
@ -1297,15 +1297,16 @@ void fix_slave_exec_mode(enum_var_type type)
DBUG_ENTER("fix_slave_exec_mode"); DBUG_ENTER("fix_slave_exec_mode");
compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT
> SLAVE_EXEC_MODE_LAST_BIT - 1); > SLAVE_EXEC_MODE_LAST_BIT - 1);
if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 && if (test_all_bits(slave_exec_mode_options,
bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
(ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{ {
sql_print_error("Ambiguous slave modes combination." sql_print_error("Ambiguous slave modes combination."
" STRICT will be used"); " STRICT will be used");
bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT); slave_exec_mode_options&= ~(ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT);
} }
if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0) if (!(slave_exec_mode_options & (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT)))
bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT); slave_exec_mode_options|= (ULL(1)<< SLAVE_EXEC_MODE_STRICT);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }

View file

@ -63,6 +63,7 @@ public:
bool report_error(THD *thd); bool report_error(THD *thd);
bool is_invalidated() const { return m_invalidated; } bool is_invalidated() const { return m_invalidated; }
void reset_reprepare_observer() { m_invalidated= FALSE; } void reset_reprepare_observer() { m_invalidated= FALSE; }
Reprepare_observer() {} /* Remove gcc warning */
private: private:
bool m_invalidated; bool m_invalidated;
}; };
@ -1117,6 +1118,7 @@ public:
/* Ignore error */ /* Ignore error */
return TRUE; return TRUE;
} }
Dummy_error_handler() {} /* Remove gcc warning */
}; };

View file

@ -5704,6 +5704,10 @@ compare_tables(TABLE *table,
*/ */
Alter_info tmp_alter_info(*alter_info, thd->mem_root); Alter_info tmp_alter_info(*alter_info, thd->mem_root);
uint db_options= 0; /* not used */ uint db_options= 0; /* not used */
/* Set default value for return value (to ensure it's always set) */
*need_copy_table= ALTER_TABLE_DATA_CHANGED;
/* Create the prepared information. */ /* Create the prepared information. */
if (mysql_prepare_create_table(thd, create_info, if (mysql_prepare_create_table(thd, create_info,
&tmp_alter_info, &tmp_alter_info,
@ -5762,7 +5766,6 @@ compare_tables(TABLE *table,
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar)) (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
{ {
DBUG_PRINT("info", ("Basic checks -> ALTER_TABLE_DATA_CHANGED")); DBUG_PRINT("info", ("Basic checks -> ALTER_TABLE_DATA_CHANGED"));
*need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -5792,7 +5795,6 @@ compare_tables(TABLE *table,
{ {
DBUG_PRINT("info", ("NULL behaviour difference in field '%s' -> " DBUG_PRINT("info", ("NULL behaviour difference in field '%s' -> "
"ALTER_TABLE_DATA_CHANGED", new_field->field_name)); "ALTER_TABLE_DATA_CHANGED", new_field->field_name));
*need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -5828,7 +5830,6 @@ compare_tables(TABLE *table,
{ {
DBUG_PRINT("info", ("!field_is_equal('%s') -> ALTER_TABLE_DATA_CHANGED", DBUG_PRINT("info", ("!field_is_equal('%s') -> ALTER_TABLE_DATA_CHANGED",
new_field->field_name)); new_field->field_name));
*need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
// Clear indexed marker // Clear indexed marker
@ -5963,7 +5964,6 @@ compare_tables(TABLE *table,
{ {
DBUG_PRINT("info", ("check_if_incompatible_data() -> " DBUG_PRINT("info", ("check_if_incompatible_data() -> "
"ALTER_TABLE_DATA_CHANGED")); "ALTER_TABLE_DATA_CHANGED"));
*need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0); DBUG_RETURN(0);
} }

View file

@ -1034,10 +1034,12 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
bool parse_status; bool parse_status;
bool result, view_is_mergeable; bool result, view_is_mergeable;
TABLE_LIST *UNINIT_VAR(view_main_select_tables); TABLE_LIST *UNINIT_VAR(view_main_select_tables);
DBUG_ENTER("mysql_make_view"); DBUG_ENTER("mysql_make_view");
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name)); DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
LINT_INIT(parse_status);
LINT_INIT(view_select);
if (table->view) if (table->view)
{ {
/* /*

View file

@ -8190,7 +8190,7 @@ function_call_generic:
builder= find_qualified_function_builder(thd); builder= find_qualified_function_builder(thd);
DBUG_ASSERT(builder); DBUG_ASSERT(builder);
item= builder->create(thd, $1, $3, true, $5); item= builder->create_with_db(thd, $1, $3, true, $5);
if (! ($$= item)) if (! ($$= item))
{ {

View file

@ -155,7 +155,8 @@ public:
/** @brief /** @brief
This method will never be called if you do not implement indexes. This method will never be called if you do not implement indexes.
*/ */
virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; } virtual double read_time(uint index, uint ranges, ha_rows rows)
{ return (double) rows / 20.0+1; }
/* /*
Everything below are methods that we implement in ha_example.cc. Everything below are methods that we implement in ha_example.cc.

View file

@ -1274,6 +1274,8 @@ static my_bool translog_set_lsn_for_files(uint32 from_file, uint32 to_file,
for (file= from_file; file <= to_file; file++) for (file= from_file; file <= to_file; file++)
{ {
LOGHANDLER_FILE_INFO info; LOGHANDLER_FILE_INFO info;
LINT_INIT(info.max_lsn);
File fd= open_logfile_by_number_no_cache(file); File fd= open_logfile_by_number_no_cache(file);
LINT_INIT_STRUCT(info); LINT_INIT_STRUCT(info);
if ((fd < 0) || if ((fd < 0) ||
@ -3967,7 +3969,8 @@ my_bool translog_init_with_table(const char *directory,
if (!old_log_was_recovered && old_flags == flags) if (!old_log_was_recovered && old_flags == flags)
{ {
LOGHANDLER_FILE_INFO info; LOGHANDLER_FILE_INFO info;
LINT_INIT_STRUCT(info); LINT_INIT(info.maria_version);
/* /*
Accessing &log_descriptor.open_files without mutex is safe Accessing &log_descriptor.open_files without mutex is safe
because it is initialization because it is initialization

View file

@ -76,8 +76,8 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
bmove512(info->keyread_buff, page_buff, info->s->block_size); bmove512(info->keyread_buff, page_buff, info->s->block_size);
/* Save position for a possible read next / previous */ /* Save position for a possible read next / previous */
info->int_keypos= info->keyread_buff + (ulonglong) info->int_keypos; info->int_keypos= info->keyread_buff + info->keypos_offset;
info->int_maxpos= info->keyread_buff + (ulonglong) info->int_maxpos; info->int_maxpos= info->keyread_buff + info->maxpos_offset;
info->int_keytree_version= key->keyinfo->version; info->int_keytree_version= key->keyinfo->version;
info->last_search_keypage= info->last_keypage; info->last_search_keypage= info->last_keypage;
info->page_changed= 0; info->page_changed= 0;
@ -214,8 +214,8 @@ static int _ma_search_no_save(register MARIA_HA *info, MARIA_KEY *key,
info->cur_row.trid= _ma_trid_from_key(&info->last_key); info->cur_row.trid= _ma_trid_from_key(&info->last_key);
/* Store offset to key */ /* Store offset to key */
info->int_keypos= (uchar*) (keypos - page.buff); info->keypos_offset= (uint) (keypos - page.buff);
info->int_maxpos= (uchar*) (maxpos - page.buff); info->maxpos_offset= (uint) (maxpos - page.buff);
info->int_nod_flag= nod_flag; info->int_nod_flag= nod_flag;
info->last_keypage= pos; info->last_keypage= pos;
*res_page_link= page_link; *res_page_link= page_link;

View file

@ -506,8 +506,10 @@ struct st_maria_handler
uchar *first_mbr_key; /* Searhed spatial key */ uchar *first_mbr_key; /* Searhed spatial key */
uchar *rec_buff; /* Temp buffer for recordpack */ uchar *rec_buff; /* Temp buffer for recordpack */
uchar *blob_buff; /* Temp buffer for blobs */ uchar *blob_buff; /* Temp buffer for blobs */
uchar *int_keypos, /* Save position for next/previous */ uchar *int_keypos; /* Save position for next/previous */
*int_maxpos; /* -""- */ uchar *int_maxpos; /* -""- */
uint keypos_offset; /* Tmp storage for offset int_keypos */
uint maxpos_offset; /* Tmp storage for offset int_maxpos */
uchar *update_field_data; /* Used by update in rows-in-block */ uchar *update_field_data; /* Used by update in rows-in-block */
uint int_nod_flag; /* -""- */ uint int_nod_flag; /* -""- */
uint32 int_keytree_version; /* -""- */ uint32 int_keytree_version; /* -""- */

View file

@ -44,9 +44,10 @@ static void FT_STOPWORD_free(FT_STOPWORD *w, TREE_FREE action,
static int ft_add_stopword(const char *w) static int ft_add_stopword(const char *w)
{ {
FT_STOPWORD sw; FT_STOPWORD sw;
return !w || return (!w ||
(((sw.len= (uint) strlen(sw.pos=(const uchar *)w)) >= ft_min_word_len) && (((sw.len= (uint) strlen((char*) (sw.pos=(const uchar *)w))) >=
(tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL)); ft_min_word_len) &&
(tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL)));
} }
int ft_init_stopwords() int ft_init_stopwords()

View file

@ -382,7 +382,7 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param)
my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
} }
DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d", DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d",
my_errno ? NULL : (long) myisam, my_errno)); my_errno ? 0L : (long) myisam, my_errno));
err: err:
DBUG_RETURN(my_errno ? NULL : myisam); DBUG_RETURN(my_errno ? NULL : myisam);

View file

@ -239,6 +239,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name,
rc= 1; rc= 1;
errpos= 0; errpos= 0;
bzero((char*) &file_cache, sizeof(file_cache)); bzero((char*) &file_cache, sizeof(file_cache));
LINT_INIT(m_info);
/* Open MERGE meta file. */ /* Open MERGE meta file. */
if ((fd= my_open(fn_format(parent_name_buff, parent_name, "", MYRG_NAME_EXT, if ((fd= my_open(fn_format(parent_name_buff, parent_name, "", MYRG_NAME_EXT,

View file

@ -0,0 +1,22 @@
# Copyright (C) 2006 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/extra/yassl/include)
ADD_LIBRARY(oqgraph ha_oqgraph.cc)

View file

@ -0,0 +1,96 @@
# Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
# ======================================================================
# Open Query Graph Computation Engine, based on a concept by Arjen Lentz
# Mk.II implementation by Antony Curtis & Arjen Lentz
# For more information, documentation, support, enhancement engineering,
# and non-GPL licensing, see http://openquery.com/graph
# or contact graph@openquery.com
# For packaged binaries, see http://ourdelta.org
# ======================================================================
mysqlplugindir= $(pkglibdir)/plugin
BOOST_CXXFLAGS = -frtti -fexceptions -fimplicit-templates
#BOOST_CXXFLAGS+= -g
#original flags before 2009-11-10
#BOOST_CXXFLAGS+= -O3 -fomit-frame-pointer -fstrict-aliasing
#BOOST_CXXFLAGS+= -momit-leaf-frame-pointer -falign-loops
#modified flags:
# - remove omit-frame-pointer, x86 specific (fails on PPC) + hinders debugging
# Option details from gcc man:
# Don't keep the frame pointer in a register for functions that don't need one.
# This avoids the instructions to save, set up and restore frame pointers;
# it also makes an extra register available in many functions.
# It also makes debugging impossible on some machines.
# (automatically gets enabled anyway by -O* on some architectures)
BOOST_CXXFLAGS+= -O3 -fstrict-aliasing
BOOST_CXXFLAGS+= -falign-loops
BOOST_CXXFLAGS+= -fvisibility-inlines-hidden
BOOST_CXXFLAGS+= -funroll-loops -fno-trapping-math
EXTRA_DIST = ha_oqgraph.h ha_oqgraph.cc graphcore.cc \
graphcore-graph.h graphcore-types.h graphcore.h \
CMakeFiles.txt plug.in oqgraph_probes.d
# DTRACE = @DTRACE@
# DTRACEFLAGS = @DTRACEFLAGS@
# DTRACEFILES = .libs/liboqgraph_engine_la-ha_oqgraph.o
ORIG_CXXFLAGS = @CXXFLAGS@
CXXFLAGS=
noinst_HEADERS = ha_oqgraph.h \
graphcore-graph.h graphcore-types.h graphcore.h
# oqgraph_probes.h
noinst_LTLIBRARIES = libgraphcore.la
libgraphcore_la_SOURCES = graphcore.cc
libgraphcore_la_CXXFLAGS = $(ORIG_CXXFLAGS) $(BOOST_CXXFLAGS)
if BUILD_OQGRAPH_FOR_MYSQL
if BUILD_OQGRAPH_STANDALONE
INCLUDES = -DDBUG_ON -DSAFE_MUTEX -DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX -DHAVE_OQGRAPH $(MYSQL_INC)
else
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/regex -I$(top_srcdir)/sql -I$(srcdir) -DHAVE_OQGRAPH
endif !BUILD_OQGRAPH_STANDALONE
EXTRA_LTLIBRARIES = oqgraph_engine.la
mysqlplugin_LTLIBRARIES = @plugin_oqgraph_shared_target@
oqgraph_engine_la_SOURCES = ha_oqgraph.cc
oqgraph_engine_la_LIBADD = libgraphcore.la
# if HAVE_DTRACE
# oqgraph_engine_la_LIBADD += oqgraph_probes.o
# endif
oqgraph_engine_la_LDFLAGS = -module -rpath $(mysqlplugindir)
oqgraph_engine_la_CFLAGS = $(ORIG_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
oqgraph_engine_la_CXXFLAGS = $(ORIG_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
# oqgraph_probes.h: oqgraph_probes.d
# $(DTRACE) $(DTRACEFLAGS) -h -s oqgraph_probes.d
# mv oqgraph_probes.h oqgraph_probes.h.bak
# sed "s/#include <unistd.h>//g" oqgraph_probes.h.bak > oqgraph_probes.h
# rm oqgraph_probes.h.bak
# oqgraph_probes.o:
# $(DTRACE) $(DTRACEFLAGS) -G -s oqgraph_probes.d $(DTRACEFILES)
endif BUILD_OQGRAPH_FOR_MYSQL
# End

16
storage/oqgraph/README Normal file
View file

@ -0,0 +1,16 @@
OQGraph storage engine
Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
The Open Query GRAPH engine (OQGRAPH) is a computation engine allowing
hierarchies and more complex graph structures to be handled in a
relational fashion. In a nutshell, tree structures and
friend-of-a-friend style searches can now be done using standard SQL
syntax, and results joined onto other tables.
See http://openquery.com/graph for more information.
INSTALLATION
OQGraph requires at least version 1.40.0 of the Boost library. To
obtain a copy of the Boost library, see http://www.boost.org/

View file

@ -0,0 +1,48 @@
/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* ======================================================================
Open Query Graph Computation Engine, based on a concept by Arjen Lentz
Mk.II implementation by Antony Curtis & Arjen Lentz
For more information, documentation, support, enhancement engineering,
and non-GPL licensing, see http://openquery.com/graph
or contact graph@openquery.com
For packaged binaries, see http://ourdelta.org
======================================================================
*/
#ifndef oq_graphcore_graph_h_
#define oq_graphcore_graph_h_
typedef adjacency_list
<
vecS,
vecS,
bidirectionalS,
VertexInfo,
EdgeInfo
> Graph;
#define GRAPH_WEIGHTMAP(G) get(&EdgeInfo::weight, G)
typedef property_map<Graph, EdgeWeight EdgeInfo::*>::type weightmap_type;
#define GRAPH_INDEXMAP(G) get(vertex_index, G)
typedef property_map<Graph, vertex_index_t>::type indexmap_type;
#define GRAPH_IDMAP(G) get(&VertexInfo::id, G)
typedef property_map<Graph, VertexID VertexInfo::*>::type idmap_type;
#endif

View file

@ -0,0 +1,36 @@
/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* ======================================================================
Open Query Graph Computation Engine, based on a concept by Arjen Lentz
Mk.II implementation by Antony Curtis & Arjen Lentz
For more information, documentation, support, enhancement engineering,
and non-GPL licensing, see http://openquery.com/graph
or contact graph@openquery.com
For packaged binaries, see http://ourdelta.org
======================================================================
*/
#ifndef oq_graphcore_types_h_
#define oq_graphcore_types_h_
namespace open_query
{
typedef unsigned long long VertexID;
typedef double EdgeWeight;
}
#endif

1101
storage/oqgraph/graphcore.cc Normal file

File diff suppressed because it is too large Load diff

116
storage/oqgraph/graphcore.h Normal file
View file

@ -0,0 +1,116 @@
/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* ======================================================================
Open Query Graph Computation Engine, based on a concept by Arjen Lentz
Mk.II implementation by Antony Curtis & Arjen Lentz
For more information, documentation, support, enhancement engineering,
and non-GPL licensing, see http://openquery.com/graph
or contact graph@openquery.com
For packaged binaries, see http://ourdelta.org
======================================================================
*/
#ifndef oq_graphcore_h_
#define oq_graphcore_h_
/* #define GRAPHCORE_INTERNAL __attribute__((visibility("hidden"))) */
#define GRAPHCORE_INTERNAL
#include "graphcore-types.h"
namespace open_query
{
class oqgraph_share;
class oqgraph_cursor;
struct row
{
bool latch_indicator;
bool orig_indicator;
bool dest_indicator;
bool weight_indicator;
bool seq_indicator;
bool link_indicator;
int latch;
VertexID orig;
VertexID dest;
EdgeWeight weight;
unsigned seq;
VertexID link;
};
class oqgraph
{
oqgraph_share *const share;
oqgraph_cursor *cursor;
row row_info;
inline oqgraph(oqgraph_share*) throw();
inline ~oqgraph() throw();
public:
enum error_code
{
OK= 0,
NO_MORE_DATA,
EDGE_NOT_FOUND,
INVALID_WEIGHT,
DUPLICATE_EDGE,
CANNOT_ADD_VERTEX,
CANNOT_ADD_EDGE,
MISC_FAIL
};
struct current_row_st {};
static inline current_row_st current_row()
{ return current_row_st(); }
unsigned vertices_count() const throw();
unsigned edges_count() const throw();
int delete_all(void) throw();
int insert_edge(VertexID, VertexID, EdgeWeight, bool=0) throw();
int modify_edge(VertexID, VertexID, EdgeWeight) throw();
int delete_edge(VertexID, VertexID) throw();
int modify_edge(current_row_st,
VertexID*, VertexID*, EdgeWeight*, bool=0) throw();
int delete_edge(current_row_st) throw();
int replace_edge(VertexID orig, VertexID dest, EdgeWeight weight) throw()
{ return insert_edge(orig, dest, weight, true); }
int search(int*, VertexID*, VertexID*) throw();
int random(bool) throw();
int fetch_row(row&) throw();
int fetch_row(row&, const void*) throw();
void row_ref(void*) throw();
static oqgraph* create(oqgraph_share*) throw();
static oqgraph_share *create() throw();
static void free(oqgraph*) throw();
static void free(oqgraph_share*) throw();
static const size_t sizeof_ref;
};
}
#endif

View file

@ -0,0 +1,356 @@
/*
* Graph Engine - Copyright (C) 2007 by Arjen Lentz (arjen@openquery.com.au)
* graphstore.c internal storage system
*/
#include <stdlib.h>
#include <string.h>
#include <my_global.h>
#include <my_sys.h>
#include "graphstore.h"
/*
create a new vertex, and add it to the list (or start a list)
NOTE! gspp is ptr to base ptr
returns 1 for ok, 0 for error
*/
static int _add_vertex (GRAPHSTORE **gspp, GRAPH_VERTEXID id)
{
GRAPHSTORE *newgsp;
GRAPHSTORE *gscurp;
if (gspp == NULL)
return 0;
/* not allowing 0 */
if (!id)
return 0;
if (*gspp != NULL) {
for (gscurp = *gspp; gscurp != NULL; gscurp = gscurp->next) {
if (gscurp->vertex->id == id)
return 1; /* we can ignore, id already exists */
}
}
/* allocate and initialise */
if ((newgsp = my_malloc(sizeof (GRAPHSTORE),MYF(MY_ZEROFILL))) == NULL)
return 0;
if ((newgsp->vertex = my_malloc(sizeof (GRAPH_VERTEX),MYF(MY_ZEROFILL))) == NULL) {
my_free(newgsp,MYF(0));
return 0;
}
newgsp->vertex->id = id;
/* add new vertex to end of list */
if (*gspp != NULL) {
for (gscurp = *gspp; gscurp->next != NULL; gscurp = gscurp->next);
gscurp->next = newgsp;
}
else /* new list */
*gspp = newgsp;
/* ok */
return 1;
}
/*
find a vertex by id
returns ptr or NULL
*/
static GRAPH_VERTEX *_find_vertex (GRAPHSTORE *gsp, GRAPH_VERTEXID id)
{
/* just loop through the list to find id */
while (gsp != NULL && gsp->vertex->id != id)
gsp = gsp->next;
/* return ptr to vertex, or NULL */
return (gsp != NULL ? gsp->vertex : NULL);
}
/*
add edge
both vertices must already exist; graphstore_insert() does this
return 1 for ok, 0 for error (already exists, alloc error, etc)
*/
static int _add_edge (GRAPHSTORE *gsp, GRAPH_VERTEXID origid, GRAPH_VERTEXID destid, GRAPH_WEIGHT weight)
{
GRAPH_VERTEX *origvp, *destvp;
GRAPH_EDGE *ep, *newep;
/* find both vertices */
if ((origvp = _find_vertex(gsp,origid)) == NULL ||
(destvp = _find_vertex(gsp,destid)) == NULL)
return 0;
/* check if edge already exists */
for (ep = origvp->forward_edge; ep != NULL; ep = ep->next_edge) {
if (ep->vertex->id == destid)
return 0;
}
/* allocate and initialise new edge */
if ((newep = my_malloc(sizeof (GRAPH_EDGE),MYF(MY_ZEROFILL))) == NULL)
return 0;
newep->vertex = destvp;
newep->weight = weight;
/* insert new edge at start of chain, that's easiest */
ep = origvp->forward_edge;
origvp->forward_edge = newep;
newep->next_edge = ep;
/* ok */
return 1;
}
/*
create a new row, and add it to the graph set (or start set)
NOTE! gsetpp is ptr to base ptr
returns 1 for ok, 0 for error
*/
static int _add_graph_set (GRAPH_SET **gsetpp, GRAPH_TUPLE *gtp)
{
GRAPH_SET *newgsetp;
GRAPH_SET *gsetcurp;
if (gsetpp == NULL || gtp == NULL)
return 0;
/* allocate and initialise */
if ((newgsetp = my_malloc(sizeof (GRAPH_SET),MYF(MY_ZEROFILL))) == NULL)
return 0;
/* put in the data */
memcpy(&newgsetp->tuple,gtp,sizeof (GRAPH_TUPLE));
/* add new row to end of set */
if (*gsetpp != NULL) {
for (gsetcurp = *gsetpp; gsetcurp->next != NULL; gsetcurp = gsetcurp->next);
gsetcurp->next = newgsetp;
}
else { /* new set */
*gsetpp = newgsetp;
}
/* ok */
return 1;
}
/*
free a graph set (release memory)
returns 1 for ok, 0 for error
*/
int free_graph_set (GRAPH_SET *gsetp)
{
GRAPH_SET *nextgsetp;
if (gsetp == NULL)
return 0;
while (gsetp != NULL) {
nextgsetp = gsetp->next;
/* free() is a void function, nothing to check */
my_free(gsetp,MYF(0));
gsetp = nextgsetp;
}
/* ok */
return 1;
}
/*
insert new data into graphstore
this can be either a vertex or an edge, depending on the params
NOTE! gspp is ptr to base ptr
returns 1 for ok, 0 for error
*/
int graphstore_insert (GRAPHSTORE **gspp, GRAPH_TUPLE *gtp)
{
if (gspp == NULL)
return 0;
/* if nada or no orig vertex, we can't do anything */
if (gtp == NULL || !gtp->origid)
return 0;
#if 0
printf("inserting: origid=%lu destid=%lu weight=%lu\n",gtp->origid,gtp->destid,gtp->weight);
#endif
if (!gtp->destid) /* no edge param so just adding vertex */
return _add_vertex(gspp,gtp->origid);
/*
add an edge
first add both vertices just in case they didn't yet exist...
not checking result there: if there's a prob, _add_edge() will catch.
*/
_add_vertex(gspp,gtp->origid);
_add_vertex(gspp,gtp->destid);
return _add_edge(*gspp,gtp->origid,gtp->destid,gtp->weight);
}
/*
this is an internal function used by graphstore_query()
find any path from originating vertex to destid
if found, add to the result set on the way back
NOTE: recursive function!
returns 1 for hit, 0 for nothing, -1 for error
*/
int _find_any_path(GRAPH_SET **gsetpp, GRAPH_VERTEXID origid, GRAPH_VERTEXID destid, GRAPH_VERTEX *gvp, GRAPH_SEQ depth)
{
GRAPH_EDGE *gep;
GRAPH_TUPLE tup;
int res;
if (gvp->id == destid) {
/* found target! */
bzero(&tup,sizeof (GRAPH_TUPLE));
tup.origid = origid;
tup.destid = destid;
tup.seq = depth;
tup.linkid = gvp->id;
return (_add_graph_set(gsetpp,&tup) ? 1 : -1);
}
/* walk through all edges for this vertex */
for (gep = gvp->forward_edge; gep; gep = gep->next_edge) {
/* recurse */
res = _find_any_path(gsetpp,origid,destid,gep->vertex,depth+1);
if (res < 0)
return res;
if (res > 0) {
/* found somewhere below this one, insert ourselves and return */
bzero(&tup,sizeof (GRAPH_TUPLE));
tup.origid = origid;
tup.destid = destid;
tup.weight = gep->weight;
tup.seq = depth;
tup.linkid = gvp->id;
return (_add_graph_set(gsetpp,&tup) ? 1 : -1);
}
}
/* nothing found but no error */
return 0;
}
/*
query graphstore
latch specifies what operation to perform
we need to feed the conditions in... (through engine condition pushdown)
for now we just presume one condition per field so we just feed in a tuple
this also means we can just find constants, not ranges
return ptr to GRAPH_SET
caller must free with free_graph_set()
*/
GRAPH_SET *graphstore_query (GRAPHSTORE *gsp, GRAPH_TUPLE *gtp)
{
GRAPH_SET *gsetp = NULL;
GRAPH_SET *gsetcurp;
GRAPH_SET *newgsetp;
if (gsp == NULL || gtp == NULL)
return (NULL);
switch (gtp->latch) {
case 0: /* return all vertices/edges */
{
GRAPHSTORE *gscurp;
GRAPH_EDGE *gep;
GRAPH_TUPLE tup;
/* walk through all vertices */
for (gscurp = gsp; gscurp != NULL; gscurp = gscurp->next) {
/* check for condition */
if (gtp->origid && gscurp->vertex->id != gtp->origid)
continue;
bzero(&tup,sizeof (GRAPH_TUPLE));
tup.origid = gscurp->vertex->id;
/* no edges? */
if (gscurp->vertex->forward_edge == NULL) {
/* just add vertex to set */
if (!_add_graph_set(&gsetp,&tup)) {
if (gsetp != NULL) /* clean up */
my_free(gsetp,MYF(0));
return (NULL);
}
}
else {
/* walk through all edges */
for (gep = gscurp->vertex->forward_edge; gep; gep = gep->next_edge) {
tup.destid = gep->vertex->id;
tup.weight = gep->weight;
/* just add vertex to set */
if (!_add_graph_set(&gsetp,&tup)) {
if (gsetp != NULL) /* clean up */
my_free(gsetp,MYF(0));
return (NULL);
}
}
}
}
}
break;
case 1: /* find a path between origid and destid */
/* yes it'll just go with the first path it finds! */
{
GRAPHSTORE *gscurp;
GRAPH_VERTEX *origvp;
GRAPH_TUPLE tup;
if (!gtp->origid || !gtp->destid)
return NULL;
/* find both vertices */
if ((origvp = _find_vertex(gsp,gtp->origid)) == NULL ||
_find_vertex(gsp,gtp->destid) == NULL)
return NULL;
if (_find_any_path(&gsetp,gtp->origid,gtp->destid,origvp,0) < 0) { /* error? */
if (gsetp != NULL) /* clean up */
my_free(gsetp,MYF(0));
return NULL;
}
}
break;
default:
/* this ends up being an empty set */
break;
}
/* Fix up latch column with the proper value - to be relationally correct */
for (gsetcurp = gsetp; gsetcurp != NULL; gsetcurp = gsetcurp->next)
gsetcurp->tuple.latch = gtp->latch;
return gsetp;
}
/* end of graphstore.c */

View file

@ -0,0 +1,90 @@
/*
* Graph Engine - Copyright (C) 2007 by Arjen Lentz (arjen@openquery.com.au)
* graphstore.h internal storage system
*/
//typedef unsigned short uint16;
//typedef unsigned long long uint64;
/*
This is essentially what a GRAPH engine table looks like on the MySQL end:
CREATE TABLE foo (
latch SMALLINT UNSIGNED NULL,
origid BIGINT UNSIGNED NULL,
destid BIGINT UNSIGNED NULL,
weight BIGINT UNSIGNED NULL,
seq BIGINT UNSIGNED NULL,
linkid BIGINT UNSIGNED NULL
) ENGINE=OQGRAPH
*/
/*
We represent the above in C in the following way:
*/
typedef uint16 GRAPH_LATCH;
typedef uint64 GRAPH_VERTEXID;
typedef uint64 GRAPH_WEIGHT;
typedef uint64 GRAPH_SEQ;
typedef struct graph_tuple {
GRAPH_LATCH latch; /* function */
GRAPH_VERTEXID origid; /* vertex (should be != 0) */
GRAPH_VERTEXID destid; /* edge */
GRAPH_WEIGHT weight; /* weight */
GRAPH_SEQ seq; /* seq# within (origid) */
GRAPH_VERTEXID linkid; /* current step between origid/destid */
} GRAPH_TUPLE;
typedef struct graph_set {
GRAPH_TUPLE tuple;
struct graph_set *next;
} GRAPH_SET;
/*
Internally, sets look nothing like the above
- We have vertices, connected by edges.
- Each vertex' edges are maintained in a linked list.
- Edges can be weighted.
There are some issues with this structure, it'd be a pest to do a delete
So for now, let's just not support deletes!
*/
/* the below is half-gross and will likely change */
typedef struct graph_edge {
struct graph_vertex {
GRAPH_VERTEXID id;
struct graph_edge *forward_edge;
} *vertex;
GRAPH_WEIGHT weight;
struct graph_edge *next_edge;
} GRAPH_EDGE;
typedef struct graph_vertex GRAPH_VERTEX;
/*
A rough internal storage system for a set
*/
/* this below is fully gross and will definitely change */
typedef struct graphstore {
GRAPH_VERTEX *vertex; /* changed to ptr when integrating into MySQL */
struct graphstore *next;
} GRAPHSTORE;
#ifdef __cplusplus
extern "C" {
#endif
/* public function declarations */
int graphstore_insert (GRAPHSTORE **gspp, GRAPH_TUPLE *gtp);
GRAPH_SET *graphstore_query (GRAPHSTORE *gsp, GRAPH_TUPLE *gtp);
int free_graph_set (GRAPH_SET *gsetp);
#ifdef __cplusplus
}
#endif
/* end of graphstore.h */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,114 @@
/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
Portions of this file copyright (C) 2000-2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* ======================================================================
Open Query Graph Computation Engine, based on a concept by Arjen Lentz
Mk.II implementation by Antony Curtis & Arjen Lentz
For more information, documentation, support, enhancement engineering,
and non-GPL licensing, see http://openquery.com/graph
or contact graph@openquery.com
For packaged binaries, see http://ourdelta.org
======================================================================
*/
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
#endif
typedef struct oqgraph_info_st OQGRAPH_INFO;
#if MYSQL_VERSION_ID >= 50120
typedef uchar byte;
#endif
namespace open_query
{
struct row;
class oqgraph;
}
/* class for the the Open Query Graph handler */
class ha_oqgraph: public handler
{
OQGRAPH_INFO *share;
open_query::oqgraph *graph;
THR_LOCK_DATA lock;
/* number of records changed since last statistics update */
uint records_changed;
uint key_stat_version;
bool replace_dups, ignore_dups, insert_dups;
int fill_record(byte*, const open_query::row&);
public:
#if MYSQL_VERSION_ID >= 50100
ha_oqgraph(handlerton *hton, TABLE_SHARE *table);
ulonglong table_flags() const;
#else
ha_oqgraph(TABLE *table);
ulong table_flags() const;
#endif
~ha_oqgraph() {}
const char *table_type() const
{
return "OQGRAPH";
}
const char *index_type(uint inx)
{
return "HASH";
}
/* Rows also use a fixed-size format */
enum row_type get_row_type() const { return ROW_TYPE_FIXED; }
const char **bas_ext() const;
ulong index_flags(uint inx, uint part, bool all_parts) const;
uint max_supported_keys() const { return MAX_KEY; }
uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
double scan_time() { return (double) 1000000000; }
double read_time(uint index, uint ranges, ha_rows rows)
{ return 1; }
int open(const char *name, int mode, uint test_if_locked);
int close(void);
int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data);
int delete_row(const byte * buf);
int index_read(byte * buf, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
int index_next_same(byte * buf, const byte * key, uint key_len);
int rnd_init(bool scan);
int rnd_next(byte *buf);
int rnd_pos(byte * buf, byte *pos);
void position(const byte *record);
int info(uint);
int extra(enum ha_extra_function operation);
int external_lock(THD *thd, int lock_type);
int delete_all_rows(void);
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
int delete_table(const char *from);
int rename_table(const char * from, const char * to);
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
void update_create_info(HA_CREATE_INFO *create_info);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
int cmp_ref(const byte *ref1, const byte *ref2);
private:
void update_key_stats();
};

View file

@ -0,0 +1,73 @@
/* src/oqgraph_config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Enables DTRACE Support */
#undef HAVE_DTRACE
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <syslimits.h> header file. */
#undef HAVE_SYSLIMITS_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Source directory for MySQL */
#undef MYSQL_SRC
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

View file

@ -0,0 +1,19 @@
/* Copyright (C) 2004-2005 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
provider oqgraph {
probe open();
probe close();
};

24
storage/oqgraph/plug.in Normal file
View file

@ -0,0 +1,24 @@
MYSQL_STORAGE_ENGINE(oqgraph,,[Graph Storage Engine],
[Open Query Graph Computation Engine], [])
MYSQL_PLUGIN_DYNAMIC(oqgraph, [oqgraph_engine.la])
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(oqgraph, [ha_oqgraph.cc])
AM_CONDITIONAL([BUILD_OQGRAPH_FOR_MYSQL], true)
AM_CONDITIONAL([BUILD_OQGRAPH_STANDALONE], false)
AM_CONDITIONAL([HAVE_DTRACE], false)
AC_LANG_PUSH([C++])
AC_MSG_CHECKING([for Boost usable by OQGraph engine])
AC_PREPROC_IFELSE(
[
#include <boost/version.hpp>
#if BOOST_VERSION >= 104000
#else
#error oops
#endif
],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
with_plugin_oqgraph=no])
AC_LANG_POP()

View file

@ -517,7 +517,7 @@ UNIV_INLINE
rec_t* rec_t*
page_rec_get_next( page_rec_get_next(
/*==============*/ /*==============*/
rec_t* rec); /*!< in: pointer to record */ const rec_t* rec); /*!< in: pointer to record */
/************************************************************//** /************************************************************//**
Gets the pointer to the next record on the page. Gets the pointer to the next record on the page.
@return pointer to next record */ @return pointer to next record */

View file

@ -731,7 +731,7 @@ UNIV_INLINE
rec_t* rec_t*
page_rec_get_next( page_rec_get_next(
/*==============*/ /*==============*/
rec_t* rec) /*!< in: pointer to record */ const rec_t* rec) /*!< in: pointer to record */
{ {
return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec))); return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec)));
} }

View file

@ -158,7 +158,7 @@ Inserts a NODE2 after NODE1 in a list.
/** Invalidate the pointers in a list node. /** Invalidate the pointers in a list node.
@param NAME list name @param NAME list name
@param N pointer to the node that was removed */ @param N pointer to the node that was removed */
# define UT_LIST_REMOVE_CLEAR(NAME, N) while (0) # define UT_LIST_REMOVE_CLEAR(NAME, N) {} while (0)
#endif #endif
/*******************************************************************//** /*******************************************************************//**

View file

@ -203,7 +203,7 @@ static int my_strnncoll_ucs2(CHARSET_INFO *cs,
my_bool t_is_prefix) my_bool t_is_prefix)
{ {
int s_res,t_res; int s_res,t_res;
my_wc_t UNINIT_VAR(s_wc),t_wc; my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen; const uchar *se=s+slen;
const uchar *te=t+tlen; const uchar *te=t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@ -317,7 +317,7 @@ static int my_strncasecmp_ucs2(CHARSET_INFO *cs,
const char *s, const char *t, size_t len) const char *s, const char *t, size_t len)
{ {
int s_res,t_res; int s_res,t_res;
my_wc_t UNINIT_VAR(s_wc),t_wc; my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const char *se=s+len; const char *se=s+len;
const char *te=t+len; const char *te=t+len;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@ -1384,7 +1384,7 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *cs,
my_bool t_is_prefix) my_bool t_is_prefix)
{ {
int s_res,t_res; int s_res,t_res;
my_wc_t UNINIT_VAR(s_wc),t_wc; my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen; const uchar *se=s+slen;
const uchar *te=t+tlen; const uchar *te=t+tlen;

View file

@ -2308,7 +2308,7 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs,
my_bool t_is_prefix) my_bool t_is_prefix)
{ {
int s_res,t_res; int s_res,t_res;
my_wc_t UNINIT_VAR(s_wc), t_wc; my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen; const uchar *se=s+slen;
const uchar *te=t+tlen; const uchar *te=t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@ -2378,7 +2378,7 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs,
my_bool diff_if_only_endspace_difference) my_bool diff_if_only_endspace_difference)
{ {
int s_res, t_res, res; int s_res, t_res, res;
my_wc_t UNINIT_VAR(s_wc),t_wc; my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se= s+slen, *te= t+tlen; const uchar *se= s+slen, *te= t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;

View file

@ -39,6 +39,7 @@ sync/sync0rw\.c: unused parameter
sync/sync0sync\.c: unused parameter sync/sync0sync\.c: unused parameter
sync/sync0sync\.c: unused variable sync/sync0sync\.c: unused variable
ut/ut0ut\.c: ignoring return value of ut/ut0ut\.c: ignoring return value of
srv/srv0srv\.c: value computed is not used
# #
# bdb is not critical to keep up to date # bdb is not critical to keep up to date
@ -65,6 +66,16 @@ db_vrfy.c : .*comparison is always false due to limited range of data type.*
# #
/usr/share/aclocal/audiofile.m4 : .* /usr/share/aclocal/audiofile.m4 : .*
#
# Ignore strict-aliasing warnings (for now)
#
.*: break strict-aliasing rules
#
# Ignore not important declaration warnings
#
.*: only defines private constructors and has no friends
# #
# Ignore all conversion warnings on windows 64 # Ignore all conversion warnings on windows 64
# (Is safe as we are not yet supporting strings >= 2G) # (Is safe as we are not yet supporting strings >= 2G)
@ -99,6 +110,11 @@ db_vrfy.c : .*comparison is always false due to limited range of data type.*
# #
storage/maria/ma_pagecache.c: .*'info_check_pin' defined but not used storage/maria/ma_pagecache.c: .*'info_check_pin' defined but not used
#
# Pbxt
#
xaction_xt\.cc: may be used uninitialized in this function
# #
# I think these are due to mix of C and C++. # I think these are due to mix of C and C++.
# #
@ -112,6 +128,7 @@ include/runtime.hpp: .*pure_error.*
.*/extra/yassl/taocrypt/src/blowfish\.cpp: array subscript is above array bounds .*/extra/yassl/taocrypt/src/blowfish\.cpp: array subscript is above array bounds
.*/extra/yassl/taocrypt/src/file\.cpp: ignoring return value .*/extra/yassl/taocrypt/src/file\.cpp: ignoring return value
.*/extra/yassl/taocrypt/src/integer\.cpp: control reaches end of non-void function .*/extra/yassl/taocrypt/src/integer\.cpp: control reaches end of non-void function
mySTL/algorithm\.hpp: is used uninitialized in this function
# #
# Groff warnings on OpenSUSE. # Groff warnings on OpenSUSE.
@ -123,18 +140,18 @@ include/runtime.hpp: .*pure_error.*
# #
listener.cc : .*conversion from 'SOCKET' to 'int'.* listener.cc : .*conversion from 'SOCKET' to 'int'.*
net_serv.cc : .*conversion from 'SOCKET' to 'int'.* net_serv.cc : .*conversion from 'SOCKET' to 'int'.*
set_var.cc: right-hand operand of comma has no effect : 1000-1400
# allow a little moving space for the warning below # allow a little moving space for the warning below
mi_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600 mi_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
ma_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650 ma_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
# #
# Wrong compiler warnings # Wrong compiler warnings
# #
.* : .*no matching operator delete found; memory will not be freed if initialization throws an exception.* .* : .*no matching operator delete found; memory will not be freed if initialization throws an exception.*
ctype-simple.c : .*unary minus operator applied to unsigned type, result still unsigned.* ctype-simple\.c : .*unary minus operator applied to unsigned type, result still unsigned.*
# Wrong warning due to GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29478 # Wrong warning due to GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29478
regexec\.c : .*passing argument 3 of.*matcher.* discards qualifiers from pointer target type.* regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type
libmysql\.c: passing argument 2 of .*memcpy.* discards qualifiers from pointer target type : 3000-4000
storage/xtradb/dict/dict0dict\.c: passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500

View file

@ -258,7 +258,7 @@ void do_tests()
#define test_kill_strategy(X) \ #define test_kill_strategy(X) \
diag("kill strategy: " #X); \ diag("kill strategy: " #X); \
DBUG_EXECUTE("reset_file", \ DBUG_EXECUTE("reset_file", \
{ rewind(DBUG_FILE); (void) ftruncate(fileno(DBUG_FILE), 0); }); \ { rewind(DBUG_FILE); my_chsize(fileno(DBUG_FILE), 0, 0, MYF(MY_WME)); }); \
DBUG_PRINT("info", ("kill strategy: " #X)); \ DBUG_PRINT("info", ("kill strategy: " #X)); \
kill_strategy=X; \ kill_strategy=X; \
do_one_test(); do_one_test();