Commit ab3abfec authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/data0/bk/mysql-5.1

into  bk-internal.mysql.com:/data0/bk/mysql-5.1-arch
parents da50aa20 02d71f7b
......@@ -29,7 +29,8 @@
#define MYSQL_STORAGE_ENGINE_PLUGIN 1 /* Storage Engine */
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
#define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */
#define MYSQL_MAX_PLUGIN_TYPE_NUM 4 /* The number of plugin types */
#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */
#define MYSQL_MAX_PLUGIN_TYPE_NUM 5 /* The number of plugin types */
/* We use the following strings to define licenses for plugins */
#define PLUGIN_LICENSE_PROPRIETARY 0
......@@ -302,6 +303,13 @@ struct st_mysql_ftparser
/* handlertons of different MySQL releases are incompatible */
#define MYSQL_DAEMON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*************************************************************************
API for I_S plugin. (MYSQL_INFORMATION_SCHEMA_PLUGIN)
*/
/* handlertons of different MySQL releases are incompatible */
#define MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*************************************************************************
API for Storage Engine plugin. (MYSQL_STORAGE_ENGINE_PLUGIN)
*/
......@@ -330,5 +338,15 @@ struct st_mysql_daemon
int interface_version;
};
/*
Here we define only the descriptor structure, that is referred from
st_mysql_plugin.
*/
struct st_mysql_information_schema
{
int interface_version;
};
#endif
drop table if exists t1,t2,t3,t4,t5;
DROP TABLE if exists t1,t2,t3,t4,t5,t6;
SET storage_engine=ARCHIVE;
CREATE TABLE t1 (
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
......@@ -184,7 +185,7 @@ fld1 fld3
250503 heaving
250504 population
250505 bomb
create table t3 engine=archive select * FROM t2;
CREATE TABLE t3 engine=archive select * FROM t2;
select * FROM t3 where fld3='bonfire';
auto fld1 companynr fld3 fld4 fld5 fld6
1191 068504 00 bonfire corresponds positively
......@@ -12358,7 +12359,7 @@ CREATE TABLE `t5` (
`a` int(11) NOT NULL auto_increment,
b char(12),
PRIMARY KEY (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
) DEFAULT CHARSET=latin1;
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
......@@ -12366,6 +12367,7 @@ INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (32, "foo");
INSERT INTO t5 VALUES (23, "foo");
ERROR 23000: Can't write; duplicate key in table 't5'
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (3, "foo");
......@@ -12379,7 +12381,6 @@ a b
4 foo
5 foo
32 foo
23 foo
33 foo
34 foo
35 foo
......@@ -12391,7 +12392,7 @@ CREATE TABLE `t5` (
`a` int(11) NOT NULL auto_increment,
b char(12),
KEY (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 AUTO_INCREMENT=5;
) DEFAULT CHARSET=latin1 AUTO_INCREMENT=5;
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
......@@ -12443,7 +12444,7 @@ CREATE TABLE `t5` (
`a` int(11) NOT NULL auto_increment,
b blob(12),
KEY (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
) DEFAULT CHARSET=latin1;
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "We the people");
INSERT INTO t5 VALUES (NULL, "in order to form a more pefect union");
......@@ -12496,7 +12497,7 @@ CREATE TABLE `t5` (
b blob(12),
c blob(12),
KEY (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
) DEFAULT CHARSET=latin1;
INSERT INTO t5 VALUES (NULL, "foo", "grok this!");
INSERT INTO t5 VALUES (NULL, "We the people", NULL);
INSERT INTO t5 VALUES (NULL, "in order to form a more peefect union", "secure the blessing of liberty");
......@@ -12545,8 +12546,8 @@ SELECT c FROM t5 WHERE a IN (32, 23, 5);
c
NULL
posterity
drop table t1;
create table t1 (v varchar(32));
DROP TABLE t1;
CREATE TABLE t1 (v varchar(32)) ;
insert into t1 values ('def'),('abc'),('hij'),('3r4f');
select * from t1;
v
......@@ -12554,68 +12555,34 @@ def
abc
hij
3r4f
alter table t1 change v v2 varchar(32);
ALTER TABLE t1 change v v2 varchar(32);
select * from t1;
v2
def
abc
hij
3r4f
alter table t1 change v2 v varchar(64);
ALTER TABLE t1 change v2 v varchar(64);
select * from t1;
v
def
abc
hij
3r4f
update t1 set v = 'lmn' where v = 'hij';
select * from t1;
v
def
abc
lmn
3r4f
alter table t1 add i int auto_increment not null primary key first;
ALTER TABLE t1 add i int auto_increment not null primary key first;
select * from t1;
i v
1 def
2 abc
3 lmn
4 3r4f
update t1 set i=5 where i=3;
select * from t1;
i v
1 def
2 abc
5 lmn
4 3r4f
alter table t1 change i i bigint;
select * from t1;
i v
1 def
2 abc
5 lmn
4 3r4f
alter table t1 add unique key (i, v);
select * from t1 where i between 2 and 4 and v in ('def','3r4f','lmn');
i v
3 hij
4 3r4f
alter table t1 data directory="$MYSQLTEST_VARDIR/tmp";
Warnings:
Warning 0 DATA DIRECTORY option ignored
select * from t1;
i v
1 def
2 abc
4 3r4f
5 lmn
DROP TABLE t5;
CREATE TABLE `t5` (
`a` int(11) NOT NULL auto_increment,
b varchar(250),
c varchar(800),
KEY (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
) DEFAULT CHARSET=latin1;
INSERT INTO t5 VALUES (NULL, "foo", "grok this!");
INSERT INTO t5 VALUES (NULL, "We the people", NULL);
INSERT INTO t5 VALUES (NULL, "in order to form a more peefect union", "secure the blessing of liberty");
......@@ -12636,4 +12603,66 @@ a b c
23 provide for the common defense posterity
33 promote the general welfare do ordain
34 abcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyz do ordain
drop table t1, t2, t4, t5;
CREATE TABLE `t6` (
`a` int(11) NOT NULL auto_increment,
b blob(12),
c int,
KEY (`a`)
) DEFAULT CHARSET=latin1;
SELECT * FROM t6;
a b c
INSERT INTO t6 VALUES (NULL, "foo", NULL);
INSERT INTO t6 VALUES (NULL, "We the people", 5);
INSERT INTO t6 VALUES (NULL, "in order to form a more pefect union", 9);
INSERT INTO t6 VALUES (NULL, "establish justice", NULL);
INSERT INTO t6 VALUES (NULL, NULL, NULL);
INSERT INTO t6 VALUES (32, "ensure domestic tranquility", NULL);
INSERT INTO t6 VALUES (23, "provide for the common defense", 30);
INSERT INTO t6 VALUES (NULL, "fo fooo", 70);
INSERT INTO t6 VALUES (NULL, NULL, 98);
INSERT INTO t6 VALUES (NULL, "promote the general welfare", 50);
SELECT * FROM t6;
a b c
1 foo NULL
2 We the people 5
3 in order to form a more pefect union 9
4 establish justice NULL
5 NULL NULL
32 ensure domestic tranquility NULL
23 provide for the common defense 30
33 fo fooo 70
34 NULL 98
35 promote the general welfare 50
SELECT * FROM t6 ORDER BY a;
a b c
1 foo NULL
2 We the people 5
3 in order to form a more pefect union 9
4 establish justice NULL
5 NULL NULL
23 provide for the common defense 30
32 ensure domestic tranquility NULL
33 fo fooo 70
34 NULL 98
35 promote the general welfare 50
SELECT * FROM t6 ORDER BY a DESC;
a b c
35 promote the general welfare 50
34 NULL 98
33 fo fooo 70
32 ensure domestic tranquility NULL
23 provide for the common defense 30
5 NULL NULL
4 establish justice NULL
3 in order to form a more pefect union 9
2 We the people 5
1 foo NULL
SHOW CREATE TABLE t6;
Table Create Table
t6 CREATE TABLE `t6` (
`a` int(11) NOT NULL AUTO_INCREMENT,
`b` tinyblob,
`c` int(11) DEFAULT NULL,
KEY `a` (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1
DROP TABLE t1, t2, t4, t5, t6;
......@@ -6,9 +6,11 @@
-- source include/have_binlog_format_mixed_or_statement.inc
--disable_warnings
drop table if exists t1,t2,t3,t4,t5;
DROP TABLE if exists t1,t2,t3,t4,t5,t6;
--enable_warnings
SET storage_engine=ARCHIVE;
CREATE TABLE t1 (
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
......@@ -1294,7 +1296,7 @@ select fld1,fld3 FROM t2 where fld1 like "25050_";
#
# Test rename of table
#
create table t3 engine=archive select * FROM t2;
CREATE TABLE t3 engine=archive select * FROM t2;
select * FROM t3 where fld3='bonfire';
select count(*) FROM t3;
# Clean up path in error message
......@@ -1356,7 +1358,7 @@ while (`SELECT COUNT(auto)!=1214 FROM t2`)
}
SELECT COUNT(auto) FROM t2;
# Adding test for alter table
# Adding test for ALTER TABLE
ALTER TABLE t2 DROP COLUMN fld6;
SHOW CREATE TABLE t2;
SELECT * FROM t2;
......@@ -1369,7 +1371,7 @@ CREATE TABLE `t5` (
`a` int(11) NOT NULL auto_increment,
b char(12),
PRIMARY KEY (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
) DEFAULT CHARSET=latin1;
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
......@@ -1377,6 +1379,7 @@ INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (32, "foo");
--error 1022
INSERT INTO t5 VALUES (23, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
......@@ -1393,7 +1396,7 @@ CREATE TABLE `t5` (
`a` int(11) NOT NULL auto_increment,
b char(12),
KEY (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 AUTO_INCREMENT=5;
) DEFAULT CHARSET=latin1 AUTO_INCREMENT=5;
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "foo");
......@@ -1419,7 +1422,7 @@ CREATE TABLE `t5` (
`a` int(11) NOT NULL auto_increment,
b blob(12),
KEY (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
) DEFAULT CHARSET=latin1;
INSERT INTO t5 VALUES (NULL, "foo");
INSERT INTO t5 VALUES (NULL, "We the people");
......@@ -1447,7 +1450,7 @@ CREATE TABLE `t5` (
b blob(12),
c blob(12),
KEY (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
) DEFAULT CHARSET=latin1;
INSERT INTO t5 VALUES (NULL, "foo", "grok this!");
INSERT INTO t5 VALUES (NULL, "We the people", NULL);
......@@ -1464,35 +1467,24 @@ SELECT c FROM t5;
SELECT c FROM t5 WHERE a =3;
SELECT c FROM t5 WHERE a IN (32, 23, 5);
# Adding this in case someone tries to add fast alter table and doesn't tes
# Adding this in case someone tries to add fast ALTER TABLE and doesn't tes
# it.
# Some additional tests for new, faster alter table. Note that most of the
# whole alter table code is being tested all around the test suite already.
# Some additional tests for new, faster ALTER TABLE. Note that most of the
# whole ALTER TABLE code is being tested all around the test suite already.
#
drop table t1;
create table t1 (v varchar(32));
DROP TABLE t1;
CREATE TABLE t1 (v varchar(32)) ;
insert into t1 values ('def'),('abc'),('hij'),('3r4f');
select * from t1;
# Fast alter, no copy performed
alter table t1 change v v2 varchar(32);
ALTER TABLE t1 change v v2 varchar(32);
select * from t1;
# Fast alter, no copy performed
alter table t1 change v2 v varchar(64);
select * from t1;
update t1 set v = 'lmn' where v = 'hij';
select * from t1;
# Regular alter table
alter table t1 add i int auto_increment not null primary key first;
ALTER TABLE t1 change v2 v varchar(64);
select * from t1;
update t1 set i=5 where i=3;
select * from t1;
alter table t1 change i i bigint;
select * from t1;
alter table t1 add unique key (i, v);
select * from t1 where i between 2 and 4 and v in ('def','3r4f','lmn');
alter table t1 data directory="$MYSQLTEST_VARDIR/tmp";
# Regular ALTER TABLE
ALTER TABLE t1 add i int auto_increment not null primary key first;
select * from t1;
# Testing cleared row key
......@@ -1503,7 +1495,7 @@ CREATE TABLE `t5` (
b varchar(250),
c varchar(800),
KEY (`a`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
) DEFAULT CHARSET=latin1;
INSERT INTO t5 VALUES (NULL, "foo", "grok this!");
INSERT INTO t5 VALUES (NULL, "We the people", NULL);
......@@ -1516,11 +1508,35 @@ INSERT INTO t5 VALUES (NULL, "abcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyz
SELECT * FROM t5;
CREATE TABLE `t6` (
`a` int(11) NOT NULL auto_increment,
b blob(12),
c int,
KEY (`a`)
) DEFAULT CHARSET=latin1;
SELECT * FROM t6;
INSERT INTO t6 VALUES (NULL, "foo", NULL);
INSERT INTO t6 VALUES (NULL, "We the people", 5);
INSERT INTO t6 VALUES (NULL, "in order to form a more pefect union", 9);
INSERT INTO t6 VALUES (NULL, "establish justice", NULL);
INSERT INTO t6 VALUES (NULL, NULL, NULL);
INSERT INTO t6 VALUES (32, "ensure domestic tranquility", NULL);
INSERT INTO t6 VALUES (23, "provide for the common defense", 30);
INSERT INTO t6 VALUES (NULL, "fo fooo", 70);
INSERT INTO t6 VALUES (NULL, NULL, 98);
INSERT INTO t6 VALUES (NULL, "promote the general welfare", 50);
SELECT * FROM t6;
SELECT * FROM t6 ORDER BY a;
SELECT * FROM t6 ORDER BY a DESC;
SHOW CREATE TABLE t6;
#
# Cleanup, test is over
#
--disable_warnings
drop table t1, t2, t4, t5;
DROP TABLE t1, t2, t4, t5, t6;
--enable_warnings
......@@ -19,18 +19,20 @@ MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
MYSQLLIBdir= $(pkglibdir)
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
-I$(srcdir)
-I$(top_srcdir)/regex \
-I$(top_srcdir)/sql \
-I$(srcdir) @ZLIB_INCLUDES@
EXTRA_LTLIBRARIES = libdaemon_example.la
pkglib_LTLIBRARIES = @plugin_daemon_example_shared_target@
libdaemon_example_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
libdaemon_example_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
libdaemon_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
libdaemon_example_la_SOURCES = daemon_example.c
libdaemon_example_la_SOURCES = daemon_example.cc
EXTRA_LIBRARIES = libdaemon_example.a
noinst_LIBRARIES = @plugin_daemon_example_static_target@
libdaemon_example_a_CXXFLAGS = $(AM_CFLAGS)
libdaemon_example_a_CFLAGS = $(AM_CFLAGS)
libdaemon_example_a_SOURCES= daemon_example.c
libdaemon_example_a_SOURCES= daemon_example.cc
......@@ -13,10 +13,13 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <mysql_priv.h>
#include <stdlib.h>
#include <ctype.h>
#include <mysql_version.h>
#include <mysql/plugin.h>
#include <my_global.h>
#include <my_dir.h>
/*
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
......@@ -24,7 +27,44 @@
#endif
*/
#define HEART_STRING_BUFFER 100
struct mysql_heartbeat_context
{
pthread_t heartbeat_thread;
File heartbeat_file;
};
pthread_handler_t mysql_heartbeat(void *p)
{
DBUG_ENTER("mysql_heartbeat");
struct mysql_heartbeat_context *con= (struct mysql_heartbeat_context *)p;
char buffer[HEART_STRING_BUFFER];
unsigned int x= 0;
time_t result;
struct tm tm_tmp;
while(1)
{
sleep(5);
result= time(NULL);
localtime_r(&result, &tm_tmp);
my_snprintf(buffer, sizeof(buffer),
"Heartbeat at %02d%02d%02d %2d:%02d:%02d\n",
tm_tmp.tm_year % 100,
tm_tmp.tm_mon+1,
tm_tmp.tm_mday,
tm_tmp.tm_hour,
tm_tmp.tm_min,
tm_tmp.tm_sec);
my_write(con->heartbeat_file, buffer, strlen(buffer), MYF(0));
x++;
}
DBUG_RETURN(0);
}
/*
Initialize the daemon example at server start or plugin installation.
......@@ -33,7 +73,7 @@
daemon_example_plugin_init()
DESCRIPTION
Does nothing.
Starts up heartbeatbeat thread
RETURN VALUE
0 success
......@@ -42,7 +82,51 @@
static int daemon_example_plugin_init(void *p)
{
return(0);
DBUG_ENTER("daemon_example_plugin_init");
struct mysql_heartbeat_context *con;
pthread_attr_t attr; /* Thread attributes */
char heartbeat_filename[FN_REFLEN];
char buffer[HEART_STRING_BUFFER];
time_t result= time(NULL);
struct tm tm_tmp;
struct st_plugin_int *plugin= (struct st_plugin_int *)p;
con= (struct mysql_heartbeat_context *)my_malloc(sizeof(struct mysql_heartbeat_context), MYF(0));
fn_format(heartbeat_filename, "mysql-heartbeat", "", ".log", MY_REPLACE_EXT | MY_UNPACK_FILENAME);
unlink(heartbeat_filename);
con->heartbeat_file= my_open(heartbeat_filename, O_CREAT|O_RDWR, MYF(0));
/*
No threads exist at this point in time, so this is thread safe.
*/
localtime_r(&result, &tm_tmp);
my_snprintf(buffer, sizeof(buffer),
"Starting up at %02d%02d%02d %2d:%02d:%02d\n",
tm_tmp.tm_year % 100,
tm_tmp.tm_mon+1,
tm_tmp.tm_mday,
tm_tmp.tm_hour,
tm_tmp.tm_min,
tm_tmp.tm_sec);
my_write(con->heartbeat_file, buffer, strlen(buffer), MYF(0));
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,
PTHREAD_CREATE_JOINABLE);
/* now create the thread */
if (pthread_create(&con->heartbeat_thread, &attr, mysql_heartbeat, (void *)con) != 0)
{
fprintf(stderr,"Could not create heartbeat thread!\n");
exit(0);
}
plugin->data= (void *)con;
DBUG_RETURN(0);
}
......@@ -58,10 +142,33 @@ static int daemon_example_plugin_init(void *p)
1 failure (cannot happen)
*/
static int daemon_example_plugin_deinit(void *p)
{
return(0);
DBUG_ENTER("daemon_example_plugin_deinit");
char buffer[HEART_STRING_BUFFER];
struct st_plugin_int *plugin= (struct st_plugin_int *)p;
struct mysql_heartbeat_context *con= (struct mysql_heartbeat_context *)plugin->data;
time_t result= time(NULL);
struct tm tm_tmp;
pthread_cancel(con->heartbeat_thread);
localtime_r(&result, &tm_tmp);
my_snprintf(buffer, sizeof(buffer),
"Shutting down at %02d%02d%02d %2d:%02d:%02d\n",
tm_tmp.tm_year % 100,
tm_tmp.tm_mon+1,
tm_tmp.tm_mday,
tm_tmp.tm_hour,
tm_tmp.tm_min,
tm_tmp.tm_sec);
my_write(con->heartbeat_file, buffer, strlen(buffer), MYF(0));
my_close(con->heartbeat_file, MYF(0));
my_free((char *)con, MYF(0));
DBUG_RETURN(0);
}
struct st_mysql_daemon daemon_example_plugin=
......@@ -77,7 +184,7 @@ mysql_declare_plugin(daemon_example)
&daemon_example_plugin,
"daemon_example",
"Brian Aker",
"Daemon example that tests init and deinit of a plugin",
"Daemon example, creates a heartbeat beat file in mysql-heartbeat.log",
PLUGIN_LICENSE_GPL,
daemon_example_plugin_init, /* Plugin Init */
daemon_example_plugin_deinit, /* Plugin Deinit */
......
......@@ -31,17 +31,26 @@ const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{ C_STRING_WITH_LEN("UDF") },
{ C_STRING_WITH_LEN("STORAGE ENGINE") },
{ C_STRING_WITH_LEN("FTPARSER") },
{ C_STRING_WITH_LEN("DAEMON") }
{ C_STRING_WITH_LEN("DAEMON") },
{ C_STRING_WITH_LEN("INFORMATION SCHEMA") }
};
extern int initialize_schema_table(st_plugin_int *plugin);
extern int finalize_schema_table(st_plugin_int *plugin);
/*
The number of elements in both plugin_type_initialize and
plugin_type_deinitialize should equal to the number of plugins
defined.
*/
plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
0,ha_initialize_handlerton,0,0
0,ha_initialize_handlerton,0,0,initialize_schema_table
};
plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
0,ha_finalize_handlerton,0,0
0,ha_finalize_handlerton,0,0,finalize_schema_table
};
static const char *plugin_interface_version_sym=
......@@ -58,14 +67,16 @@ static int min_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
0x0000,
MYSQL_HANDLERTON_INTERFACE_VERSION,
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION
MYSQL_DAEMON_INTERFACE_VERSION,
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
};
static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
0x0000, /* UDF: not implemented */
MYSQL_HANDLERTON_INTERFACE_VERSION,
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION
MYSQL_DAEMON_INTERFACE_VERSION,
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
};
static DYNAMIC_ARRAY plugin_dl_array;
......
......@@ -2451,10 +2451,48 @@ int make_db_list(THD *thd, List<char> *files,
mysql_data_home, NullS, 1) != FIND_FILES_OK);
}
struct st_add_schema_table
{
List<char> *files;
const char *wild;
};
static my_bool add_schema_table(THD *thd, st_plugin_int *plugin,
void* p_data)
{
st_add_schema_table *data= (st_add_schema_table *)p_data;
List<char> *file_list= data->files;
const char *wild= data->wild;
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
DBUG_ENTER("add_schema_table");
if (schema_table->hidden)
DBUG_RETURN(0);
if (wild)
{
if (lower_case_table_names)
{
if (wild_case_compare(files_charset_info,
schema_table->table_name,
wild))
DBUG_RETURN(0);
}
else if (wild_compare(schema_table->table_name, wild, 0))
DBUG_RETURN(0);
}
if (file_list->push_back(thd->strdup(schema_table->table_name)))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
int schema_tables_add(THD *thd, List<char> *files, const char *wild)
{
ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
st_add_schema_table add_data;
DBUG_ENTER("schema_tables_add");
for (; tmp_schema_table->table_name; tmp_schema_table++)
{
if (tmp_schema_table->hidden)
......@@ -2472,9 +2510,16 @@ int schema_tables_add(THD *thd, List<char> *files, const char *wild)
continue;
}
if (files->push_back(thd->strdup(tmp_schema_table->table_name)))
return 1;
DBUG_RETURN(1);
}
return 0;
add_data.files= files;
add_data.wild= wild;
if (plugin_foreach(thd, add_schema_table,
MYSQL_INFORMATION_SCHEMA_PLUGIN, &add_data))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
......@@ -4511,6 +4556,44 @@ get_referential_constraints_record(THD *thd, struct st_table_list *tables,
DBUG_RETURN(0);
}
struct schema_table_ref
{
const char *table_name;
ST_SCHEMA_TABLE *schema_table;
};
/*
Find schema_tables elment by name
SYNOPSIS
find_schema_table_in_plugin()
thd thread handler
plugin plugin
table_name table name
RETURN
0 table not found
1 found the schema table
*/
static my_bool find_schema_table_in_plugin(THD *thd, st_plugin_int *plugin,
void* p_table)
{
schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
const char* table_name= p_schema_table->table_name;
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
DBUG_ENTER("find_schema_table_in_plugin");
if (!my_strcasecmp(system_charset_info,
schema_table->table_name,
table_name)) {
p_schema_table->schema_table= schema_table;
DBUG_RETURN(1);
}
DBUG_RETURN(0);
}
/*
Find schema_tables elment by name
......@@ -4527,15 +4610,24 @@ get_referential_constraints_record(THD *thd, struct st_table_list *tables,
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
{
schema_table_ref schema_table_a;
ST_SCHEMA_TABLE *schema_table= schema_tables;
DBUG_ENTER("find_schema_table");
for (; schema_table->table_name; schema_table++)
{
if (!my_strcasecmp(system_charset_info,
schema_table->table_name,
table_name))
return schema_table;
DBUG_RETURN(schema_table);
}
return 0;
schema_table_a.table_name= table_name;
if (plugin_foreach(thd, find_schema_table_in_plugin,
MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
DBUG_RETURN(schema_table_a.schema_table);
DBUG_RETURN(NULL);
}
......@@ -5752,3 +5844,54 @@ ST_SCHEMA_TABLE schema_tables[]=
template class List_iterator_fast<char>;
template class List<char>;
#endif
int initialize_schema_table(st_plugin_int *plugin)
{
ST_SCHEMA_TABLE *schema_table;
DBUG_ENTER("initialize_schema_table");
if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
MYF(MY_WME | MY_ZEROFILL))))
DBUG_RETURN(1);
/* Historical Requirement */
plugin->data= schema_table; // shortcut for the future
if (plugin->plugin->init)
{
schema_table->create_table= create_schema_table;
schema_table->old_format= make_old_format;
schema_table->idx_field1= -1,
schema_table->idx_field2= -1;
if (plugin->plugin->init(schema_table))
{
sql_print_error("Plugin '%s' init function returned error.",
plugin->name.str);
goto err;
}
schema_table->table_name= plugin->name.str;
}
DBUG_RETURN(0);
err:
my_free((gptr)schema_table, MYF(0));
DBUG_RETURN(1);
}
int finalize_schema_table(st_plugin_int *plugin)
{
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
DBUG_ENTER("finalize_schema_table");
if (schema_table && plugin->plugin->deinit)
{
DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
if (plugin->plugin->deinit(NULL))
{
DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
plugin->name.str));
}
my_free((gptr)schema_table, MYF(0));
}
DBUG_RETURN(0);
}
......@@ -3,6 +3,7 @@
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <m_ctype.h>
#include <my_getopt.h>
#include <mysql_version.h>
......@@ -15,10 +16,12 @@ static void get_options(int *argc,char * * *argv);
static void print_version(void);
static void usage(void);
static const char *opt_tmpdir;
static const char *new_auto_increment_value;
static const char *new_auto_increment;
unsigned long long new_auto_increment_value;
static const char *load_default_groups[]= { "archive_reader", 0 };
static char **default_argv;
int opt_check, opt_force, opt_quiet, opt_backup= 0;
int opt_check, opt_force, opt_quiet, opt_backup= 0, opt_extract_frm;
int opt_autoincrement;
int main(int argc, char *argv[])
{
......@@ -40,6 +43,35 @@ int main(int argc, char *argv[])
return 0;
}
if (opt_autoincrement)
{
azio_stream writer_handle;
if (new_auto_increment_value)
{
if (reader_handle.auto_increment >= new_auto_increment_value)
{
printf("Value is lower then current value\n");
goto end;
}
}
else
{
new_auto_increment_value= reader_handle.auto_increment + 1;
}
if (!(ret= azopen(&writer_handle, argv[0], O_CREAT|O_RDWR|O_BINARY)))
{
printf("Could not open file for update: %s\n", argv[0]);
goto end;
}
writer_handle.auto_increment= new_auto_increment_value;
azclose(&writer_handle);
azflush(&reader_handle, Z_SYNC_FLUSH);
}
printf("Version %u\n", reader_handle.version);
if (reader_handle.version > 2)
{
......@@ -53,6 +85,20 @@ int main(int argc, char *argv[])
printf("\tLongest Row %u\n", reader_handle.longest_row);
printf("\tShortest Row %u\n", reader_handle.shortest_row);
printf("\tState %s\n", ( reader_handle.dirty ? "dirty" : "clean"));
printf("\tFRM stored at %u\n", reader_handle.frm_start_pos);
printf("\tComment stored at %u\n", reader_handle.comment_start_pos);
printf("\tData starts at %u\n", (unsigned int)reader_handle.start);
if (reader_handle.frm_start_pos)
printf("\tFRM length %u\n", reader_handle.frm_length);
if (reader_handle.comment_start_pos)
{
char *comment =
(char *) malloc(sizeof(char) * reader_handle.comment_length);
azread_comment(&reader_handle, comment);
printf("\tComment length %u\n\t\t%.*s\n", reader_handle.comment_length,
reader_handle.comment_length, comment);
free(comment);
}
}
else
{
......@@ -148,6 +194,23 @@ int main(int argc, char *argv[])
}
writer_handle.auto_increment= reader_handle.auto_increment;
if (reader_handle.frm_length)
{
char *ptr;
ptr= (char *)my_malloc(sizeof(char) * reader_handle.frm_length, MYF(0));
azread_frm(&reader_handle, ptr);
azwrite_frm(&writer_handle, ptr, reader_handle.frm_length);
my_free(ptr, MYF(0));
}
if (reader_handle.comment_length)
{
char *ptr;
ptr= (char *)my_malloc(sizeof(char) * reader_handle.comment_length, MYF(0));
azread_comment(&reader_handle, ptr);
azwrite_comment(&writer_handle, ptr, reader_handle.comment_length);
my_free(ptr, MYF(0));
}
while ((read= azread(&reader_handle, (byte *)size_buffer,
ARCHIVE_ROW_HEADER_SIZE, &error)))
......@@ -192,6 +255,18 @@ int main(int argc, char *argv[])
azclose(&writer_handle);
}
if (opt_extract_frm)
{
File frm_file;
char *ptr;
frm_file= my_open(argv[1], O_CREAT|O_RDWR|O_BINARY, MYF(0));
ptr= (char *)my_malloc(sizeof(char) * reader_handle.frm_length, MYF(0));
azread_frm(&reader_handle, ptr);
my_write(frm_file, ptr, reader_handle.frm_length, MYF(0));
my_close(frm_file, MYF(0));
my_free(ptr, MYF(0));
}
end:
printf("\n");
azclose(&reader_handle);
......@@ -211,6 +286,9 @@ get_one_option(int optid,
case 'c':
opt_check= 1;
break;
case 'e':
opt_extract_frm= 1;
break;
case 'f':
opt_force= 1;
printf("Not implemented yet\n");
......@@ -226,7 +304,11 @@ get_one_option(int optid,
printf("Not implemented yet\n");
break;
case 'A':
printf("Not implemented yet\n");
opt_autoincrement= 1;
if (argument)
new_auto_increment_value= strtoull(argument, NULL, 0);
else
new_auto_increment_value= 0;
break;
case '?':
usage();
......@@ -257,6 +339,9 @@ static struct my_option my_long_options[] =
"Output debug log. Often this is 'd:t:o,filename'.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"extract-frm", 'e',
"Extract the frm file.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"force", 'f',
"Restart with -r if there are any errors in the table.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
......@@ -268,9 +353,9 @@ static struct my_option my_long_options[] =
{"repair", 'r', "Repair a damaged Archive version 3 or above file.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"set-auto-increment", 'A',
"Force auto_increment to start at this or higher value.",
(gptr*) &new_auto_increment_value,
(gptr*) &new_auto_increment_value,
"Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.",
(gptr*) &new_auto_increment,
(gptr*) &new_auto_increment,
0, GET_ULL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"silent", 's',
"Only print errors. One can use two -s to make archive_reader very silent.",
......
......@@ -17,11 +17,14 @@
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <my_getopt.h>
#include <mysql_version.h>
#define ARCHIVE_ROW_HEADER_SIZE 4
#define COMMENT_STRING "Your bases"
#define FRM_STRING "My bases"
#define TEST_FILENAME "test.az"
#define TEST_STRING_INIT "YOU don't know about me without you have read a book by the name of The Adventures of Tom Sawyer; but that ain't no matter. That book was made by Mr. Mark Twain, and he told the truth, mainly. There was things which he stretched, but mainly he told the truth. That is nothing. I never seen anybody but lied one time or another, without it was Aunt Polly, or the widow, or maybe Mary. Aunt Polly--Tom's Aunt Polly, she is--and Mary, and the Widow Douglas is all told about in that book, which is mostly a true book, with some stretchers, as I said before. Now the way that the book winds up is this: Tom and me found the money that the robbers hid in the cave, and it made us rich. We got six thousand dollars apiece--all gold. It was an awful sight of money when it was piled up. Well, Judge Thatcher he took it and put it out at interest, and it fetched us a dollar a day apiece all the year round --more than a body could tell what to do with. The Widow Douglas she took me for her son, and allowed she would..."
#define TEST_LOOP_NUM 100
......@@ -44,6 +47,7 @@ int size_test(unsigned long long length, unsigned long long rows_to_test_for);
int main(int argc, char *argv[])
{
unsigned int ret;
char comment_str[10];
int error;
unsigned int x;
......@@ -67,6 +71,19 @@ int main(int argc, char *argv[])
return 0;
}
azwrite_comment(&writer_handle, (char *)COMMENT_STRING,
(unsigned int)strlen(COMMENT_STRING));
azread_comment(&writer_handle, comment_str);
assert(!memcmp(COMMENT_STRING, comment_str,
strlen(COMMENT_STRING)));
azwrite_frm(&writer_handle, (char *)FRM_STRING,
(unsigned int)strlen(FRM_STRING));
azread_frm(&writer_handle, comment_str);
assert(!memcmp(FRM_STRING, comment_str,
strlen(FRM_STRING)));
if (!(ret= azopen(&reader_handle, TEST_FILENAME, O_RDONLY|O_BINARY)))
{
printf("Could not open test file\n");
......@@ -87,6 +104,10 @@ int main(int argc, char *argv[])
}
azflush(&writer_handle, Z_SYNC_FLUSH);
azread_comment(&writer_handle, comment_str);
assert(!memcmp(COMMENT_STRING, comment_str,
strlen(COMMENT_STRING)));
/* Lets test that our internal stats are good */
assert(writer_handle.rows == TEST_LOOP_NUM);
......@@ -94,15 +115,16 @@ int main(int argc, char *argv[])
azflush(&reader_handle, Z_SYNC_FLUSH);
assert(reader_handle.rows == TEST_LOOP_NUM);
assert(reader_handle.auto_increment == 0);
assert(reader_handle.check_point == 62);
assert(reader_handle.check_point == 96);
assert(reader_handle.forced_flushes == 1);
assert(reader_handle.comment_length == 10);
assert(reader_handle.dirty == AZ_STATE_SAVED);
writer_handle.auto_increment= 4;
azflush(&writer_handle, Z_SYNC_FLUSH);
assert(writer_handle.rows == TEST_LOOP_NUM);
assert(writer_handle.auto_increment == 4);
assert(writer_handle.check_point == 62);
assert(writer_handle.check_point == 96);
assert(writer_handle.forced_flushes == 2);
assert(writer_handle.dirty == AZ_STATE_SAVED);
......@@ -181,7 +203,7 @@ int main(int argc, char *argv[])
azflush(&reader_handle, Z_SYNC_FLUSH);
assert(reader_handle.rows == 102);
assert(reader_handle.auto_increment == 4);
assert(reader_handle.check_point == 1256);
assert(reader_handle.check_point == 1290);
assert(reader_handle.forced_flushes == 4);
assert(reader_handle.dirty == AZ_STATE_SAVED);
......
......@@ -128,7 +128,12 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd)
s->longest_row= 0;
s->auto_increment= 0;
s->check_point= 0;
s->comment_start_pos= 0;
s->comment_length= 0;
s->frm_start_pos= 0;
s->frm_length= 0;
s->dirty= 1; /* We create the file dirty */
s->start = AZHEADER_SIZE + AZMETA_BUFFER_SIZE;
write_header(s);
my_seek(s->file, 0, MY_SEEK_END, MYF(0));
}
......@@ -153,7 +158,6 @@ void write_header(azio_stream *s)
char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
char *ptr= buffer;
s->start = AZHEADER_SIZE + AZMETA_BUFFER_SIZE;
s->block_size= AZ_BUFSIZE;
s->version = (unsigned char)az_magic[1];
s->minor_version = (unsigned char)az_magic[2];
......@@ -167,8 +171,12 @@ void write_header(azio_stream *s)
*(ptr + AZ_BLOCK_POS)= (unsigned char)(s->block_size/1024); /* Reserved for block size */
*(ptr + AZ_STRATEGY_POS)= (unsigned char)Z_DEFAULT_STRATEGY; /* Compression Type */
int4store(ptr + AZ_FRM_POS, 0); /* FRM Block */
int4store(ptr + AZ_FRM_POS, s->frm_start_pos); /* FRM Block */
int4store(ptr + AZ_FRM_LENGTH_POS, s->frm_length); /* FRM Block */
int4store(ptr + AZ_COMMENT_POS, s->comment_start_pos); /* COMMENT Block */
int4store(ptr + AZ_COMMENT_LENGTH_POS, s->comment_length); /* COMMENT Block */
int4store(ptr + AZ_META_POS, 0); /* Meta Block */
int4store(ptr + AZ_META_LENGTH_POS, 0); /* Meta Block */
int8store(ptr + AZ_START_POS, (unsigned long long)s->start); /* Start of Data Block Index Block */
int8store(ptr + AZ_ROW_POS, (unsigned long long)s->rows); /* Start of Data Block Index Block */
int8store(ptr + AZ_FLUSH_POS, (unsigned long long)s->forced_flushes); /* Start of Data Block Index Block */
......@@ -176,10 +184,12 @@ void write_header(azio_stream *s)
int8store(ptr + AZ_AUTOINCREMENT_POS, (unsigned long long)s->auto_increment); /* Start of Data Block Index Block */
int4store(ptr+ AZ_LONGEST_POS , s->longest_row); /* Longest row */
int4store(ptr+ AZ_SHORTEST_POS, s->shortest_row); /* Shorest row */
int4store(ptr+ AZ_FRM_POS,
AZHEADER_SIZE + AZMETA_BUFFER_SIZE); /* FRM position */
*(ptr + AZ_DIRTY_POS)= (unsigned char)s->dirty; /* Start of Data Block Index Block */
/* Always begin at the begining, and end there as well */
my_pwrite(s->file, buffer, (uint)s->start, 0, MYF(0));
my_pwrite(s->file, buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0, MYF(0));
}
/* ===========================================================================
......@@ -303,6 +313,8 @@ void check_header(azio_stream *s)
buffer[len]= get_byte(s);
s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
read_header(s, buffer);
for (; len < s->start; len++)
get_byte(s);
}
else
{
......@@ -326,6 +338,10 @@ void read_header(azio_stream *s, unsigned char *buffer)
s->auto_increment= (unsigned long long)uint8korr(buffer + AZ_AUTOINCREMENT_POS);
s->longest_row= (unsigned int)uint4korr(buffer + AZ_LONGEST_POS);
s->shortest_row= (unsigned int)uint4korr(buffer + AZ_SHORTEST_POS);
s->frm_start_pos= (unsigned int)uint4korr(buffer + AZ_FRM_POS);
s->frm_length= (unsigned int)uint4korr(buffer + AZ_FRM_LENGTH_POS);
s->comment_start_pos= (unsigned int)uint4korr(buffer + AZ_COMMENT_POS);
s->comment_length= (unsigned int)uint4korr(buffer + AZ_COMMENT_LENGTH_POS);
s->dirty= (unsigned int)buffer[AZ_DIRTY_POS];
}
else
......@@ -497,7 +513,6 @@ unsigned int azwrite (azio_stream *s, voidpc buf, unsigned int len)
s->stream.next_in = (Bytef*)buf;
s->stream.avail_in = len;
s->rows++;
while (s->stream.avail_in != 0)
......@@ -782,3 +797,65 @@ int azclose (azio_stream *s)
return destroy(s);
}
/*
Though this was added to support MySQL's FRM file, anything can be
stored in this location.
*/
int azwrite_frm(azio_stream *s, char *blob, unsigned int length)
{
if (s->mode == 'r')
return 1;
if (s->rows > 0)
return 1;
s->frm_start_pos= s->start;
s->frm_length= length;
s->start+= length;
my_pwrite(s->file, blob, s->frm_length, s->frm_start_pos, MYF(0));
write_header(s);
my_seek(s->file, 0, MY_SEEK_END, MYF(0));
return 0;
}
int azread_frm(azio_stream *s, char *blob)
{
my_pread(s->file, blob, s->frm_length, s->frm_start_pos, MYF(0));
return 0;
}
/*
Simple comment field
*/
int azwrite_comment(azio_stream *s, char *blob, unsigned int length)
{
if (s->mode == 'r')
return 1;
if (s->rows > 0)
return 1;
s->comment_start_pos= s->start;
s->comment_length= length;
s->start+= length;
my_pwrite(s->file, blob, s->comment_length, s->comment_start_pos, MYF(0));
write_header(s);
my_seek(s->file, 0, MY_SEEK_END, MYF(0));
return 0;
}
int azread_comment(azio_stream *s, char *blob)
{
my_pread(s->file, blob, s->comment_length, s->comment_start_pos, MYF(0));
return 0;
}
......@@ -49,9 +49,10 @@ extern "C" {
#define AZMETA_BUFFER_SIZE sizeof(unsigned long long) \
+ sizeof(unsigned long long) + sizeof(unsigned long long) + sizeof(unsigned long long) \
+ sizeof(unsigned int) + sizeof(unsigned int) \
+ sizeof(unsigned int) + sizeof(unsigned int) \
+ sizeof(unsigned char)
#define AZHEADER_SIZE 21
#define AZHEADER_SIZE 29
#define AZ_MAGIC_POS 0
#define AZ_VERSION_POS 1
......@@ -59,15 +60,19 @@ extern "C" {
#define AZ_BLOCK_POS 3
#define AZ_STRATEGY_POS 4
#define AZ_FRM_POS 5
#define AZ_META_POS 9
#define AZ_START_POS 13
#define AZ_ROW_POS 21
#define AZ_FLUSH_POS 29
#define AZ_CHECK_POS 37
#define AZ_AUTOINCREMENT_POS 45
#define AZ_LONGEST_POS 53
#define AZ_SHORTEST_POS 57
#define AZ_DIRTY_POS 61
#define AZ_FRM_LENGTH_POS 9
#define AZ_META_POS 13
#define AZ_META_LENGTH_POS 17
#define AZ_START_POS 21
#define AZ_ROW_POS 29
#define AZ_FLUSH_POS 37
#define AZ_CHECK_POS 45
#define AZ_AUTOINCREMENT_POS 53
#define AZ_LONGEST_POS 61
#define AZ_SHORTEST_POS 65
#define AZ_COMMENT_POS 69
#define AZ_COMMENT_LENGTH_POS 73
#define AZ_DIRTY_POS 77
/*
......@@ -220,6 +225,10 @@ typedef struct azio_stream {
unsigned int longest_row; /* Longest row */
unsigned int shortest_row; /* Shortest row */
unsigned char dirty; /* State of file */
unsigned int frm_start_pos; /* Position for start of FRM */
unsigned int frm_length; /* Position for start of FRM */
unsigned int comment_start_pos; /* Position for start of comment */
unsigned int comment_length; /* Position for start of comment */
} azio_stream;
/* basic functions */
......@@ -322,6 +331,11 @@ extern int azclose(azio_stream *file);
error number (see function gzerror below).
*/
extern int azwrite_frm (azio_stream *s, char *blob, unsigned int length);
extern int azread_frm (azio_stream *s, char *blob);
extern int azwrite_comment (azio_stream *s, char *blob, unsigned int length);
extern int azread_comment (azio_stream *s, char *blob);
#ifdef __cplusplus
}
#endif
This diff is collapsed.
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