Commit 593e7ab4 authored by sasha@mysql.sashanet.com's avatar sasha@mysql.sashanet.com

Ugly merge of 3.23 changes into 4.0 - fix up needed

parents 95d908dd 8f62579c
#! /bin/sh
path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium_cflags $debug_cflags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs"
extra_configs="$extra_configs --with-debug=full --with-mysqlfs --without-server --without-pstack"
. "$path/FINISH.sh"
heikki@donna.mysql.fi heikki@donna.mysql.fi
monty@donna.mysql.fi monty@donna.mysql.fi
monty@work.mysql.com
sasha@mysql.sashanet.com sasha@mysql.sashanet.com
...@@ -22,15 +22,18 @@ TAR = gtar ...@@ -22,15 +22,18 @@ TAR = gtar
EXTRA_DIST = INSTALL-SOURCE README \ EXTRA_DIST = INSTALL-SOURCE README \
COPYING COPYING.LIB MIRRORS COPYING COPYING.LIB MIRRORS
SUBDIRS = include @docs_dirs@ @readline_dir@ \ SUBDIRS = include @docs_dirs@ @readline_dir@ \
@thread_dirs@ @sql_client_dirs@ \ @thread_dirs@ @pstack_dirs@ @sql_client_dirs@ \
@sql_server_dirs@ scripts tests man \ @sql_server_dirs@ @libmysqld_dirs@ scripts tests man \
@bench_dirs@ support-files @bench_dirs@ support-files @fs_dirs@
# Relink after clean # Relink after clean
CLEANFILES = linked_client_sources linked_server_sources linked_libmysql_sources linked_libmysql_r_sources linked_include_sources linked_sources = linked_client_sources linked_server_sources \
linked_libmysql_sources linked_libmysql_r_sources \
linked_libmysqld_sources linked_include_sources
CLEANFILES = $(linked_sources)
# This is just so that the linking is done early. # This is just so that the linking is done early.
config.h: linked_include_sources linked_client_sources linked_server_sources linked_libmysql_sources linked_libmysql_r_sources config.h: $(linked_sources)
linked_include_sources: linked_include_sources:
cd include; $(MAKE) link_sources cd include; $(MAKE) link_sources
...@@ -47,6 +50,10 @@ linked_libmysql_r_sources: linked_libmysql_sources ...@@ -47,6 +50,10 @@ linked_libmysql_r_sources: linked_libmysql_sources
cd libmysql_r; $(MAKE) link_sources cd libmysql_r; $(MAKE) link_sources
echo timestamp > linked_libmysql_r_sources echo timestamp > linked_libmysql_r_sources
linked_libmysqld_sources:
cd libmysqld; $(MAKE) link_sources
echo timestamp > linked_libmysqld_sources
#avoid recursive make calls in sql directory #avoid recursive make calls in sql directory
linked_server_sources: linked_server_sources:
cd sql; rm -f mini_client_errors.c;@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c cd sql; rm -f mini_client_errors.c;@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
......
...@@ -111,6 +111,9 @@ ...@@ -111,6 +111,9 @@
/* sigwait with one argument */ /* sigwait with one argument */
#undef HAVE_NONPOSIX_SIGWAIT #undef HAVE_NONPOSIX_SIGWAIT
/* ORBIT */
#undef HAVE_ORBIT
/* pthread_attr_setscope */ /* pthread_attr_setscope */
#undef HAVE_PTHREAD_ATTR_SETSCOPE #undef HAVE_PTHREAD_ATTR_SETSCOPE
...@@ -230,6 +233,9 @@ ...@@ -230,6 +233,9 @@
#undef USE_MB #undef USE_MB
#undef USE_MB_IDENT #undef USE_MB_IDENT
/* the pstack backtrace library */
#undef USE_PSTACK
/* Use MySQL RAID */ /* Use MySQL RAID */
#undef USE_RAID #undef USE_RAID
......
...@@ -605,6 +605,53 @@ fi ...@@ -605,6 +605,53 @@ fi
AC_MSG_RESULT($ac_cv_conv_longlong_to_float) AC_MSG_RESULT($ac_cv_conv_longlong_to_float)
]) ])
AC_DEFUN(MYSQL_CHECK_MYSQLFS, [
AC_ARG_WITH([mysqlfs],
[\
--with-mysqlfs Include the corba-based MySQL file system],
[mysqlfs="$withval"],
[mysqlfs=no])
dnl Call MYSQL_CHECK_ORBIT even if mysqlfs == no, so that @orbit_*@
dnl get substituted.
MYSQL_CHECK_ORBIT
if test "$mysqlfs" = "yes"
then
if test -n "$orbit_exec_prefix"
then
fs_dirs=fs
else
AC_MSG_ERROR([mysqlfs requires ORBit, the CORBA ORB])
fi
else
fs_dirs=
fi
AC_SUBST([fs_dirs])
])
AC_DEFUN(MYSQL_CHECK_ORBIT, [
AC_MSG_CHECKING(for ORBit)
if test `which orbit-config`
then
orbit_exec_prefix=`orbit-config --exec-prefix`
orbit_includes=`orbit-config --cflags server`
orbit_libs=`orbit-config --libs server`
orbit_idl="$orbit_exec_prefix/bin/orbit-idl"
AC_MSG_RESULT(found!)
AC_DEFINE(HAVE_ORBIT)
else
orbit_exec_prefix=
orbit_includes=
orbit_libs=
orbit_idl=
AC_MSG_RESULT(not found)
fi
AC_SUBST(orbit_includes)
AC_SUBST(orbit_libs)
AC_SUBST(orbit_idl)
])
dnl --------------------------------------------------------------------------- dnl ---------------------------------------------------------------------------
dnl Macro: MYSQL_CHECK_BDB dnl Macro: MYSQL_CHECK_BDB
dnl Sets HAVE_BERKELEY_DB if inst library is found dnl Sets HAVE_BERKELEY_DB if inst library is found
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
* Andi Gutmans <andi@zend.com> * Andi Gutmans <andi@zend.com>
* Zeev Suraski <zeev@zend.com> * Zeev Suraski <zeev@zend.com>
* Jani Tolonen <jani@mysql.com> * Jani Tolonen <jani@mysql.com>
* Matt Wagner <mwagner@mysql.com>
* Jeremy Cole <jcole@mysql.com>
* *
**/ **/
...@@ -120,7 +122,7 @@ static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, ...@@ -120,7 +122,7 @@ static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
no_rehash=0,skip_updates=0,safe_updates=0,one_database=0, no_rehash=0,skip_updates=0,safe_updates=0,one_database=0,
opt_compress=0, opt_compress=0,
vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0, vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0,
opt_nopager=1, opt_outfile=0, no_named_cmds=1; opt_xml=0,opt_nopager=1, opt_outfile=0, no_named_cmds=1;
static uint verbose=0,opt_silent=0,opt_mysql_port=0; static uint verbose=0,opt_silent=0,opt_mysql_port=0;
static my_string opt_mysql_unix_port=0; static my_string opt_mysql_unix_port=0;
static int connect_flag=CLIENT_INTERACTIVE; static int connect_flag=CLIENT_INTERACTIVE;
...@@ -131,6 +133,11 @@ static String glob_buffer,old_buffer; ...@@ -131,6 +133,11 @@ static String glob_buffer,old_buffer;
static int wait_time = 5; static int wait_time = 5;
static STATUS status; static STATUS status;
static ulong select_limit,max_join_size,opt_connect_timeout=0; static ulong select_limit,max_join_size,opt_connect_timeout=0;
static char *xmlmeta[] = {
"&", "&amp;",
"<", "&lt;",
0, 0
};
static char default_pager[FN_REFLEN]; static char default_pager[FN_REFLEN];
char pager[FN_REFLEN], outfile[FN_REFLEN]; char pager[FN_REFLEN], outfile[FN_REFLEN];
FILE *PAGER, *OUTFILE; FILE *PAGER, *OUTFILE;
...@@ -166,6 +173,9 @@ static int sql_connect(char *host,char *database,char *user,char *password, ...@@ -166,6 +173,9 @@ static int sql_connect(char *host,char *database,char *user,char *password,
uint silent); uint silent);
static int put_info(const char *str,INFO_TYPE info,uint error=0); static int put_info(const char *str,INFO_TYPE info,uint error=0);
static void safe_put_field(const char *pos,ulong length); static void safe_put_field(const char *pos,ulong length);
static char *array_value(char **array, char *key);
static char *xmlencode(char *dest, char *src);
static void my_chomp(char *end);
static void init_pager(); static void init_pager();
static void end_pager(); static void end_pager();
static void init_tee(); static void init_tee();
...@@ -250,6 +260,7 @@ static bool add_line(String &buffer,char *line,char *in_string); ...@@ -250,6 +260,7 @@ static bool add_line(String &buffer,char *line,char *in_string);
static void remove_cntrl(String &buffer); static void remove_cntrl(String &buffer);
static void print_table_data(MYSQL_RES *result); static void print_table_data(MYSQL_RES *result);
static void print_table_data_html(MYSQL_RES *result); static void print_table_data_html(MYSQL_RES *result);
static void print_table_data_xml(MYSQL_RES *result);
static void print_tab_data(MYSQL_RES *result); static void print_tab_data(MYSQL_RES *result);
static void print_table_data_vertically(MYSQL_RES *result); static void print_table_data_vertically(MYSQL_RES *result);
static ulong start_timer(void); static ulong start_timer(void);
...@@ -313,7 +324,7 @@ int main(int argc,char *argv[]) ...@@ -313,7 +324,7 @@ int main(int argc,char *argv[])
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
initialize_readline(my_progname); initialize_readline(my_progname);
if (!status.batch && !quick && !opt_html) if (!status.batch && !quick && !opt_html && !opt_xml)
{ {
/*read-history from file, default ~/.mysql_history*/ /*read-history from file, default ~/.mysql_history*/
if (getenv("MYSQL_HISTFILE")) if (getenv("MYSQL_HISTFILE"))
...@@ -351,7 +362,7 @@ sig_handler mysql_end(int sig) ...@@ -351,7 +362,7 @@ sig_handler mysql_end(int sig)
if (connected) if (connected)
mysql_close(&mysql); mysql_close(&mysql);
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
if (!status.batch && !quick && ! opt_html) if (!status.batch && !quick && !opt_html && !opt_xml)
{ {
/* write-history */ /* write-history */
if (verbose) if (verbose)
...@@ -396,6 +407,7 @@ static struct option long_options[] = ...@@ -396,6 +407,7 @@ static struct option long_options[] =
{"force", no_argument, 0, 'f'}, {"force", no_argument, 0, 'f'},
{"help", no_argument, 0, '?'}, {"help", no_argument, 0, '?'},
{"html", no_argument, 0, 'H'}, {"html", no_argument, 0, 'H'},
{"xml", no_argument, 0, 'X'},
{"host", required_argument, 0, 'h'}, {"host", required_argument, 0, 'h'},
{"ignore-spaces", no_argument, 0, 'i'}, {"ignore-spaces", no_argument, 0, 'i'},
{"no-auto-rehash",no_argument, 0, 'A'}, {"no-auto-rehash",no_argument, 0, 'A'},
...@@ -490,6 +502,7 @@ static void usage(int version) ...@@ -490,6 +502,7 @@ static void usage(int version)
-i, --ignore-space Ignore space after function names.\n\ -i, --ignore-space Ignore space after function names.\n\
-h, --host=... Connect to host.\n\ -h, --host=... Connect to host.\n\
-H, --html Produce HTML output.\n\ -H, --html Produce HTML output.\n\
-X, --xml Produce XML output.\n\
-L, --skip-line-numbers\n\ -L, --skip-line-numbers\n\
Don't write line number for errors.\n"); Don't write line number for errors.\n");
#ifndef __WIN__ #ifndef __WIN__
...@@ -564,7 +577,7 @@ static int get_options(int argc, char **argv) ...@@ -564,7 +577,7 @@ static int get_options(int argc, char **argv)
set_all_changeable_vars(changeable_vars); set_all_changeable_vars(changeable_vars);
while ((c=getopt_long(argc,argv, while ((c=getopt_long(argc,argv,
"?ABCD:LfgGHinNoqrstTU::vVw::WEe:h:O:P:S:u:#::p::", "?ABCD:LfgGHXinNoqrstTU::vVw::WEe:h:O:P:S:u:#::p::",
long_options, &option_index)) != EOF) long_options, &option_index)) != EOF)
{ {
switch(c) { switch(c) {
...@@ -685,6 +698,7 @@ static int get_options(int argc, char **argv) ...@@ -685,6 +698,7 @@ static int get_options(int argc, char **argv)
case 'G': no_named_cmds=0; break; case 'G': no_named_cmds=0; break;
case 'g': no_named_cmds=1; break; case 'g': no_named_cmds=1; break;
case 'H': opt_html=1; break; case 'H': opt_html=1; break;
case 'X': opt_xml=1; break;
case 'i': connect_flag|= CLIENT_IGNORE_SPACE; break; case 'i': connect_flag|= CLIENT_IGNORE_SPACE; break;
case 'B': case 'B':
if (!status.batch) if (!status.batch)
...@@ -1442,6 +1456,8 @@ com_go(String *buffer,char *line __attribute__((unused))) ...@@ -1442,6 +1456,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
init_pager(); init_pager();
if (opt_html) if (opt_html)
print_table_data_html(result); print_table_data_html(result);
else if (opt_xml)
print_table_data_xml(result);
else if (vertical) else if (vertical)
print_table_data_vertically(result); print_table_data_vertically(result);
else if (opt_silent && verbose <= 2 && !output_tables) else if (opt_silent && verbose <= 2 && !output_tables)
...@@ -1644,6 +1660,49 @@ print_table_data_html(MYSQL_RES *result) ...@@ -1644,6 +1660,49 @@ print_table_data_html(MYSQL_RES *result)
} }
static void
print_table_data_xml(MYSQL_RES *result)
{
MYSQL_ROW cur;
MYSQL_FIELD *fields;
mysql_field_seek(result,0);
char *statement;
statement=(char*) my_malloc(strlen(glob_buffer.ptr())*5+1, MYF(MY_WME));
xmlencode(statement, (char*) glob_buffer.ptr());
(void) my_chomp(strend(statement));
tee_fprintf(PAGER,"<?xml version=\"1.0\"?>\n\n<resultset statement=\"%s\">", statement);
my_free(statement,MYF(MY_ALLOW_ZERO_PTR));
fields = mysql_fetch_fields(result);
while ((cur = mysql_fetch_row(result)))
{
(void) tee_fputs("\n <row>\n", PAGER);
for (uint i=0; i < mysql_num_fields(result); i++)
{
char *data;
ulong *lengths=mysql_fetch_lengths(result);
data=(char*) my_malloc(lengths[i]*5+1, MYF(MY_WME));
tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
(fields[i].name[0] ? fields[i].name :
" &nbsp; ") : "NULL"));
xmlencode(data, cur[i]);
safe_put_field(data, strlen(data));
tee_fprintf(PAGER, "</%s>\n", (fields[i].name ?
(fields[i].name[0] ? fields[i].name :
" &nbsp; ") : "NULL"));
my_free(data,MYF(MY_ALLOW_ZERO_PTR));
}
(void) tee_fputs(" </row>\n", PAGER);
}
(void) tee_fputs("</resultset>\n", PAGER);
}
static void static void
print_table_data_vertically(MYSQL_RES *result) print_table_data_vertically(MYSQL_RES *result)
...@@ -1675,6 +1734,43 @@ print_table_data_vertically(MYSQL_RES *result) ...@@ -1675,6 +1734,43 @@ print_table_data_vertically(MYSQL_RES *result)
} }
} }
static char
*array_value(char **array, char *key) {
int x;
for(x=0; array[x]; x+=2)
if(!strcmp(array[x], key))
return array[x+1];
return 0;
}
static char
*xmlencode(char *dest, char *src) {
char *p = src;
char *t;
char s[2] = { 0, 0 };
*dest = 0;
do {
s[0] = *p;
if(!(t=array_value(xmlmeta, s))) t = s;
strcat(dest, t);
} while(*p++);
return dest;
}
static void
my_chomp(char *end) {
char *mend;
mend = end;
do {
if (isspace(*mend)) {
*mend = '\0';
} else
mend--;
} while (mend && *mend);
}
static void static void
safe_put_field(const char *pos,ulong length) safe_put_field(const char *pos,ulong length)
......
...@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. ...@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc) AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line! # The Docs Makefile.am parses this line!
AM_INIT_AUTOMAKE(mysql, 3.23.37) AM_INIT_AUTOMAKE(mysql, 4.0.0)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
...@@ -654,6 +654,39 @@ int main() ...@@ -654,6 +654,39 @@ int main()
if test -z "$atom_ops"; then atom_ops="no"; fi if test -z "$atom_ops"; then atom_ops="no"; fi
AC_MSG_RESULT($atom_ops) AC_MSG_RESULT($atom_ops)
AC_ARG_WITH(pstack,
[ --without-pstack Don't use the pstack backtrace library],
[USE_PSTACK=$withval],
[USE_PSTACK=yes])
pstack_libs= pstack_dirs=
if test "$USE_PSTACK" = yes
then
have_libiberty= have_libbfd=
my_save_LIBS="$LIBS"
dnl I have no idea if this is a good test - can't find docs for libiberty
AC_CHECK_LIB([iberty], [fdmatch],
[have_libiberty=yes
AC_CHECK_LIB([bfd], [bfd_openr], [have_libbfd=yes], , [-liberty])])
LIBS="$my_save_LIBS"
AC_MSG_CHECKING([for pstack libs])
if test x"$have_libiberty" = xyes -a x"$have_libbfd" = xyes
then
pstack_dirs='$(top_srcdir)'/pstack
pstack_libs="$pstack_dirs/libpstack.a -lbfd -liberty"
AC_SUBST([pstack_dirs])
AC_SUBST([pstack_libs])
AC_DEFINE([USE_PSTACK])
AC_MSG_RESULT([yes])
dnl This check isn't needed, but might be nice to give some feedback....
dnl AC_CHECK_HEADER(libiberty.h,
dnl have_libiberty_h=yes,
dnl have_libiberty_h=no)
else
AC_MSG_RESULT([no (missing libbfd)])
fi
fi
fi fi
# Check for gtty if termio.h doesn't exists # Check for gtty if termio.h doesn't exists
...@@ -1581,6 +1614,27 @@ AC_ARG_WITH(server, ...@@ -1581,6 +1614,27 @@ AC_ARG_WITH(server,
[with_server=yes] [with_server=yes]
) )
AC_ARG_WITH(embedded-server,
[ --with-embedded-server Build the embedded server (libmysqld).],
[with_embedded_server=$withval],
[with_embedded_server=no]
)
MYSQL_CHECK_MYSQLFS
libmysqld_dirs=
if test "$with_embedded_server" = "yes"
then
libmysqld_dirs=libmysqld
# We can't build embedded library without building the server, because
# we depend on libmysys, libmystrings, libmyisam, etc.
with_server=yes
fi
# XXX: We need to add @libmysqld_extra_libs@ (or whatever) so that
# mysql_config --libmysqld-libs will print out something like
# -L/path/to/lib/mysql -lmysqld -lmyisam -lmysys -lmystrings -ldbug ...
AC_SUBST([libmysqld_dirs])
# Shall we build the docs? # Shall we build the docs?
AC_ARG_WITH(docs, AC_ARG_WITH(docs,
[ --without-docs Skip building of the documentation.], [ --without-docs Skip building of the documentation.],
...@@ -2017,13 +2071,13 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile \ ...@@ -2017,13 +2071,13 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile \
strings/Makefile regex/Makefile heap/Makefile \ strings/Makefile regex/Makefile heap/Makefile \
bdb/Makefile \ bdb/Makefile \
myisam/Makefile myisammrg/Makefile \ myisam/Makefile myisammrg/Makefile \
man/Makefile \ man/Makefile readline/Makefile \
readline/Makefile libmysql_r/Makefile libmysql/Makefile client/Makefile \ libmysql_r/Makefile libmysqld/Makefile libmysql/Makefile client/Makefile \
sql/Makefile sql/share/Makefile \ pstack/Makefile sql/Makefile sql/share/Makefile \
merge/Makefile dbug/Makefile scripts/Makefile \ merge/Makefile dbug/Makefile scripts/Makefile \
include/Makefile sql-bench/Makefile \ include/Makefile sql-bench/Makefile \
tests/Makefile Docs/Makefile support-files/Makefile \ tests/Makefile Docs/Makefile support-files/Makefile \
mysql-test/Makefile \ mysql-test/Makefile fs/Makefile \
include/mysql_version.h include/mysql_version.h
, , [ , , [
test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
......
// -----------------------------------------------------------------------------
// CorbaDS Module - Implement Kernel functionality in korbit
// -----------------------------------------------------------------------------
//
// Main source of information:
// http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html
//
module CorbaFS {
struct dirent
{
long inode; // inode number
string name; // file name (null-terminated)
};
typedef sequence<dirent> DirEntSeq;
typedef sequence<octet> Buffer;
interface Inode {
void getStatus(out unsigned short mode, out unsigned long uid, out unsigned long gid,
out unsigned long size, out unsigned long inodeNum, out unsigned short numLinks,
out long atime, out long mtime, out long ctime);
void readpage(out Buffer buffer, in long size, in long offset);
void release();
};
interface FileSystem {
Inode getInode(in string path);
// DirectoryInode getStatus implementation must have S_IFDIR in the S_IFMT
// field of the mode value.
DirEntSeq readdir(in string path);
// SymlinkInode getStatus implementation must have S_IFLNK in the S_IFMT
// field of the mode value.
string readlink(in string filename);
};
};
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either 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
#called from the top level Makefile
CFLAGS = $(ORBIT_CFLAGS) -g
LFLAGS = $(ORBIT_LIBS)
orbit_idl = @orbit_idl@
orbit_includes = @orbit_includes@
orbit_libs = @orbit_libs@
DISTCLEANFILES = CorbaFS-common.* CorbaFS-stubs.* CorbaFS-skels.* CorbaFS.h
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include \
-I$(srcdir)/../regex \
-I$(srcdir) -I../include -I.. -I. \
-I$(srcdir) -I../include -I.. -I. \
$(orbit_includes)
WRAPLIBS= @WRAPLIBS@
libexec_PROGRAMS = mysqlcorbafsd
noinst_PROGRAMS =mysqlfs_test
LDADD = ../libmysql/libmysqlclient.la $(orbit_libs)
mysqlcorbafsd_LDADD = $(LDADD) $(CXXLDFLAGS)
noinst_HEADERS =
mysqlfs_test_SOURCES = mysqlcorbafs_test.c CorbaFS-common.c CorbaFS-stubs.c libmysqlfs.c
mysqlcorbafsd_SOURCES = mysqlcorbafs.c CorbaFS-skels.c database.c CorbaFS-common.c libmysqlfs.c
DEFS = -DMYSQL_SERVER \
-DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
-DDATADIR="\"$(MYSQLDATAdir)\"" \
-DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
@DEFS@
# Don't put lex_hash.h in BUILT_SOURCES as this will give infinite recursion
BUILT_SOURCES = CorbaFS-common.c CorbaFS-stubs.c CorbaFS-skels.c CorbaFS.h
EXTRA_DIST = $(BUILT_SOURCES)
#YFLAGS = -d
OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
__math.h time.h __time.h unistd.h __unistd.h types.h \
xtypes.h ac-types.h posix.h string.h __string.h \
errno.h socket.h inet.h dirent.h netdb.h \
cleanup.h cond.h debug_out.h fd.h kernel.h mutex.h \
prio_queue.h pthread_attr.h pthread_once.h queue.h\
sleep.h specific.h version.h pwd.h timers.h uio.h \
cdefs.h machdep.h signal.h __signal.h util.h lex.h \
wait.h
link_sources:
rm -f mini_client_errors.c
@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
# Don't update the files from bitkeeper
%::SCCS/s.%
idltargets : CorbaFS.idl
$(ORBIT_IDL) CorbaFS.idl
$(orbit_idl) CorbaFS.idl
# individual rules
CorbaFS-stubs.c : CorbaFS.idl
$(orbit_idl) CorbaFS.idl
CorbaFS-common.c : CorbaFS.idl
$(orbit_idl) CorbaFS.idl
CorbaFS-skels.c : CorbaFS.idl
$(orbit_idl) CorbaFS.idl
#CorbaFS-client.c : CorbaFS.h
#CorbaFS-server.c : CorbaFS.h
CorbaFS.h : CorbaFS.idl
$(orbit_idl) CorbaFS.idl
MySQL Filesystem
Tnu Samuel - tonu@mysql.com
Some additional information is available on http://no.spam.ee/~tonu/mysqlfs.html
WARNING: Experimental code and known to crash computer.
Instructions, how to get this stuff working:
1. Make sure you have ORBit, includeing development libraries installed. They should be version 0.5.3 or later.
- I am lazy man and use default ones included with my RedHat:
[root@localhost /root]# rpm -qa | grep ORBit
ORBit-0.5.3-2
ORBit-devel-0.5.3-2
[root@localhost /root]#
2. Prepare kernel to include korbit:
- Get Linux 2.4.1 kernel source. (very possibly this patch works on 2.4.0 without modifications too)
- unpack it
- apply patch named "korbit-kernel-2.4.1-patch" on it.
- make menuconfig
- In section "Networking options":
...
[*] Kernel ORB (EXPERIMENTAL)
...
<M> CORBA User-space FileSystem (EXPERIMENTAL)
...
- make dep ; make bzlilo ; make modules ; make modules_install
- reboot
- Execute: insmod /lib/modules/$(uname -r)/kernel/net/korbit/modules/CorbaFS/client/corba-corbafs-client.o
You should see "gethostname() = localhost". Look at known bug 3 in the end of this doc.
3. Make sure MySQL server is working on your system
- On my RedHat 7.0 I execute "/etc/init.d/mysqld start"
4. Prepare MySQL FS daemon
- Get MySQL 4.0 from repository OR get MySQL FS source from http://no.spam.ee/~tonu/mysqlfs.html
- unpack it. In MySQL 4.0 source this is located in directory named "fs". cd into it.
- make
- Execute command "./RunServer"
5. mount MySQL server to disk tree
- Execute command "mkdir /mnt/mysql"
- Execute command "mount -t corbafs -o `cat /tmp/mysqlcorbafs.ior` none /mnt/mysql/"
- Check you SQL server content by executing "ls -la /mnt/mysql/"
Known bugs:
1. User bugs. fix user ;)
2. MySQL FS daemon will crash or will be stopped when cobrafs is mounted, then there is no way
to unmount disks anymore. This is korbit business to handle such cases and I had no time to dig
into korbit code.
3. host name returned by gethostname() should be "localhost" or korbit will crash. Also "localhost"
must be first string after 127.0.0.1 in /etc/hosts
.libs/mysqlcorbafsd -ORBIIOPUSock=0 -ORBIIOPIPv4=1 --debug='d:t:o,~/mysqlfsd.trace' $*
#.libs/mysqlcorbafsd -ORBIIOPUSock=0 -ORBIIOPIPv4=1 $*
This diff is collapsed.
# MySQL dump 8.12
#
# Host: localhost Database: mysqlfs
#--------------------------------------------------------
# Server version 3.23.33
#
# Table structure for table 'functions'
#
CREATE TABLE functions (
type enum('server','database','table','field','key') NOT NULL default 'server',
name char(20) NOT NULL default '',
sql char(128) NOT NULL default '',
PRIMARY KEY (type,name)
) TYPE=MyISAM;
#
# Dumping data for table 'functions'
#
INSERT INTO functions VALUES ('server','uptime','SHOW STATUS like \'Uptime\'');
INSERT INTO functions VALUES ('server','version','SELECT VERSION()');
INSERT INTO functions VALUES ('table','count','SELECT COUNT(*) FROM `%table`');
INSERT INTO functions VALUES ('key','min','SELECT MIN(%key) FROM `%table`');
INSERT INTO functions VALUES ('key','max','SELECT MAX(%key) FROM `%table`');
INSERT INTO functions VALUES ('key','avg','SELECT AVG(%key) FROM `%table`');
This diff is collapsed.
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either 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
*/
#include "libmysqlfs.h"
int search_and_replace(char *search, char* replace, char* string)
{
char buff[1024];
int found=0;
char *ptr1;
const char *ptr2=buff;
char *strptr=string;
DBUG_ENTER("search_and_replace");
DBUG_PRINT("enter",("search: '%s' replace:'%s' string:'%s'",search,replace,string));
strcpy(buff,string);
while(ptr1=strstr(ptr2,search))
{
strncpy(strptr,ptr2,ptr1-buff);
strptr+=ptr1-buff;
ptr2+=ptr1-buff+strlen(search);
strcpy(strptr,replace);
strptr+=strlen(replace);
found++;
}
DBUG_RETURN(found);
}
int show_functions(char *b, function_type type)
{
int i=0,j=0;
struct func_st func;
DBUG_ENTER("show_functions");
get_dynamic(&functions_array,(gptr)&func,i);
while(func.length) {
if (func.type == type)
strcpy(&b[j++*BUFLEN],func.filename);
get_dynamic(&functions_array,(gptr)&func,++i);
}
DBUG_RETURN(j);
}
struct func_st * check_if_function(char *name, function_type type)
{
int pathlen;
int j,i=0, len;
static struct func_st function;
char buffer[BUFLEN];
DBUG_ENTER("check_if_function");
DBUG_PRINT("enter",("name: '%s' type: '%d'", name, type));
pathlen=strlen(name);
/* We try to compare last element in path to function names */
get_dynamic(&functions_array,(gptr)&function,i);
while(function.length) {
function.continuous ?
(j=!strncasecmp(function.filename, name, function.length))
: (j=!strcasecmp(function.filename,name));
if(j) { /* This happens when function was matched */
DBUG_PRINT("info",("Function %s detected!",function.filename));
break;
}
get_dynamic(&functions_array,(gptr)&function,++i);
}
/* Copy path to buffer and trip function name (if found) from it */
if(function.length != 0)
{
DBUG_RETURN(&function);
} else {
DBUG_RETURN(0);
}
}
/*
* parse - splits "path" into different variables
* in way "/server/database/table/(field|key)/(value|function)". If path is shorter,
* then other fields will be NULL. If path is longer than four levels or
* shorter than one level, FS_NOTEXIST is returned.
*/
int parse(const char * path, char *server, char * database, char *table,
char* field, char* value, struct func_st **funce)
{
char buffer[BUFLEN];
char *p=buffer;
char *x;
int len;
DBUG_ENTER("parse");
DBUG_PRINT("enter",("path: '%s'", path));
*server=*database=*table=*field=*value='\0';
/* Search for first slash and drop it */
strcpy(buffer,path);
x=strtok_r(p,"/",&p);
if(x)
{
strcpy(server,x); /* First argument is server name */
if(*p)
strcpy(database,strtok_r(p,"/",&p)); /* Second is database */
if(p && *p)
strcpy(table ,strtok_r(p,"/",&p)); /* Third is table name */
if(p && *p)
strcpy(field ,strtok_r(p,"/",&p)); /* Fourth is field or key name */
if(p && *p)
strcpy(value ,strtok_r(p,"/",&p)); /* Fifth is field/key value or function */
}
/* We have to find if last argument is function,
* In which case we clear it
*/
if(*value) {
*funce=check_if_function(value,VALUE_FUNCTION);
if(*funce) *value='\0';
} else if (*field) {
*funce=check_if_function(field,FIELD_FUNCTION);
if(*funce) *field='\0';
} else if (*table) {
*funce=check_if_function(table,TABLE_FUNCTION);
if(*funce) *table='\0';
} else if (*database) {
*funce=check_if_function(database,DATABASE_FUNCTION);
if(*funce) *database='\0';
} else if (*server) {
*funce=check_if_function(server,SERVER_FUNCTION);
if(*funce) *server='\0';
} else
*funce=NULL;
DBUG_PRINT("info",("path: '%s', server: '%s', db: '%s', table: '%s', field: '%s', value: '%s', function: '%x'",
buffer, server, database, table, field, value, funce ));
if(p && *p) /* Something is in buffer - too deep in levels */
DBUG_RETURN(-1)
else
DBUG_RETURN(0)
}
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either 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
*/
#include "CorbaFS.h"
#include <global.h>
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
#include "mysql.h"
#define BUFLEN 1024
#define MAXDIRS 1024
typedef enum {
FUNC_NONE,
FUNC_SERVER_UPTIME,
FUNC_SERVER_THREADS,
FUNC_SERVER_VERSION,
FUNC_DATABASE_CREATED,
FUNC_TABLE_COUNT,
FUNC_TABLE_CREATED,
FUNC_FIELD_LENGTH,
FUNC_KEY_AVG,
FUNC_KEY_SUM,
FUNC_KEY_MAX,
FUNC_KEY_MIN
} func_enum;
typedef enum {
NONE_FUNCTION,
ROOT_FUNCTION,
SERVER_FUNCTION,
DATABASE_FUNCTION,
TABLE_FUNCTION,
KEY_FUNCTION,
FIELD_FUNCTION,
VALUE_FUNCTION
} function_type;
struct func_st {
char type_s[20];
char filename[20];
char function[80];
function_type type;
int length;
my_bool continuous;
} ;
int parse(const char* path,
char* root,
char* database,
char* table,
char* key,
char* field,
struct func_st **func
);
gptr db_load_functions();
int db_function(char *b,const char *server, const char *database,const char *table,const char *field,
const char *value, const char *path, struct func_st *function);
int fix_filenames(char *buf);
DYNAMIC_ARRAY functions_array;
[mysqlcorbafs]
socket=/var/lib/mysql/mysql.sock
host=127.0.0.1
user=root
#password=xxxxxx
This diff is collapsed.
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either 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
*/
#include "CorbaFS.h"
#include <global.h>
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
#include "mysql.h"
#define QUOTE_CHAR '`'
/* Exit codes */
#define EX_USAGE 1
#define EX_MYSQLERR 2
#define EX_CONSCHECK 3
#define EX_EOM 4
#define CORBAFS_VERSION "0.01"
typedef struct
{
POA_CorbaFS_Inode servant;
PortableServer_POA poa;
CORBA_char *path;
CORBA_unsigned_long inodeNum;
#if 0
CORBA_unsigned_short mode;
CORBA_unsigned_long uid;
CORBA_unsigned_long gid;
CORBA_unsigned_long size;
CORBA_unsigned_short numLinks;
CORBA_long atime;
CORBA_long mtime;
CORBA_long ctime;
#endif
}
impl_POA_CorbaFS_Inode;
typedef struct
{
POA_CorbaFS_FileSystem servant;
PortableServer_POA poa;
}
impl_POA_CorbaFS_FileSystem;
/*** Implementation stub prototypes ***/
CorbaFS_FileSystem
impl_FileSystem__create(PortableServer_POA poa, CORBA_Environment * ev);
static void
impl_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
CORBA_Environment * ev);
static void
impl_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
CORBA_unsigned_short * mode,
CORBA_unsigned_long * uid,
CORBA_unsigned_long * gid,
CORBA_unsigned_long * size,
CORBA_unsigned_long * inodeNum,
CORBA_unsigned_short * numLinks,
CORBA_long * atime,
CORBA_long * mtime,
CORBA_long * ctime, CORBA_Environment * ev);
static void
impl_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
CorbaFS_Buffer ** buffer,
CORBA_long size,
CORBA_long offset, CORBA_Environment * ev);
static void
impl_Inode_release(impl_POA_CorbaFS_Inode * servant,
CORBA_Environment * ev);
static void impl_FileSystem__destroy(impl_POA_CorbaFS_FileSystem *
servant, CORBA_Environment * ev);
static CorbaFS_Inode
impl_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
CORBA_char * path, CORBA_Environment * ev);
static CorbaFS_DirEntSeq *
impl_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
CORBA_char * path,
CORBA_Environment * ev);
static CORBA_char *
impl_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
CORBA_char * filename,
CORBA_Environment * ev);
static my_bool verbose,opt_compress;
static uint opt_mysql_port=0;
static my_string opt_mysql_unix_port=0;
static int first_error=0;
static MYSQL connection, *sock=0;
extern uint opt_mysql_port;
extern my_string opt_mysql_unix_port,host,user,password;
static struct format {
char *tablestart;
char *headerrowstart;
char *headercellstart;
char *headercellseparator;
char *headercellend;
char *headerrowend;
int headerformat; /* 0 - simple, 1 - left padded, 2 - right padded */
char *contentrowstart;
char *contentcellstart;
char *contentcellseparator;
char *contentcellend;
char *contentrowend;
int contentformat;
char *footerrowstart;
char *footercellstart;
char *footercellseparator;
char *footercellend;
char *footerrowend;
int footerformat;
char *tableend;
char *leftuppercorner;
char *rightuppercorner;
char *leftdowncorner;
char *rightdowncorner;
char *leftcross;
char *rightcross;
char *topcross;
char *middlecross;
char *bottomcross;
} Human, HTML, CSF, XML;
#include <stdio.h>
#include <stdlib.h>
#include <orb/orbit.h>
#include "CorbaFS.h"
CorbaFS_FileSystem fs;
int
main (int argc, char *argv[])
{
CORBA_Environment ev;
CORBA_ORB orb;
CorbaFS_Inode inode;
CorbaFS_Buffer *buffer;
CorbaFS_DirEntSeq *dirents;
CorbaFS_dirent *dirent;
CORBA_unsigned_short mode;
CORBA_unsigned_long uid;
CORBA_unsigned_long gid;
CORBA_unsigned_long size;
CORBA_unsigned_long inodeNum;
CORBA_unsigned_short numLinks;
CORBA_long atime;
CORBA_long mtime;
CORBA_long ctime;
int i;
int niters = 10;
CORBA_exception_init(&ev);
orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
if(argc < 2)
{
printf("Need a binding ID thing as argv[1]\n");
return 1;
}
fs = CORBA_ORB_string_to_object(orb, argv[1], &ev);
if (!fs) {
printf("Cannot bind to %s\n", argv[1]);
return 1;
}
if (argc >= 3)
inode = CorbaFS_FileSystem_getInode(fs, argv[2], &ev);
else
inode = CorbaFS_FileSystem_getInode(fs, "/proc/cpuinfo", &ev);
if (!inode)
{
printf("Cannot get inode\n");
}
CorbaFS_Inode_getStatus(inode,
&mode,
&uid,
&gid,
&size,
&inodeNum,
&numLinks,
&atime,
&mtime,
&ctime,
&ev);
printf("inode = %x\n", inode);
CorbaFS_Inode_readpage(inode, &buffer, 100000, 100, &ev);
printf("readpage got %d bytes\n", buffer->_length);
printf("readpage returned : %s\n", buffer->_buffer);
if (argc >= 3)
dirents = CorbaFS_FileSystem_readdir(fs, argv[2], &ev);
else
dirents = CorbaFS_FileSystem_readdir(fs, "/", &ev);
dirent = dirents->_buffer;
for (i = 0; i < dirents->_length; i++)
{
printf("%d = %s\n", dirent->inode, dirent->name);
dirent++;
}
CORBA_Object_release(fs, &ev);
CORBA_Object_release((CORBA_Object)orb, &ev);
return 0;
}
#!/bin/sh
mountpoint=$*
if [#($mountpoint) -eq "0"];
then
exit;
fi
...@@ -49,6 +49,7 @@ FT_DOCLIST * ft_init_search(void *, uint, byte *, uint, my_bool); ...@@ -49,6 +49,7 @@ FT_DOCLIST * ft_init_search(void *, uint, byte *, uint, my_bool);
int ft_read_next(FT_DOCLIST *, char *); int ft_read_next(FT_DOCLIST *, char *);
#define ft_close_search(handler) my_free(((gptr)(handler)),MYF(0)) #define ft_close_search(handler) my_free(((gptr)(handler)),MYF(0))
#define ft_get_relevance(handler) ((handler)->doc[(handler)->curdoc].weight) #define ft_get_relevance(handler) ((handler)->doc[(handler)->curdoc].weight)
#define ft_get_docid(handler) ((handler)->doc[(handler)->curdoc].dpos)
#define ft_reinit_search(handler) (((FT_DOCLIST *)(handler))->curdoc=-1) #define ft_reinit_search(handler) (((FT_DOCLIST *)(handler))->curdoc=-1)
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -25,6 +25,10 @@ ...@@ -25,6 +25,10 @@
#define ETIME ETIMEDOUT /* For FreeBSD */ #define ETIME ETIMEDOUT /* For FreeBSD */
#endif #endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__WIN__) #if defined(__WIN__)
typedef CRITICAL_SECTION pthread_mutex_t; typedef CRITICAL_SECTION pthread_mutex_t;
...@@ -576,4 +580,8 @@ extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); ...@@ -576,4 +580,8 @@ extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
#endif /* SAFE_STATISTICS */ #endif /* SAFE_STATISTICS */
#endif /* HAVE_ATOMIC_ADD */ #endif /* HAVE_ATOMIC_ADD */
#endif /* thread_safe_increment */ #endif /* thread_safe_increment */
#ifdef __cplusplus
}
#endif
#endif /* _my_ptread_h */ #endif /* _my_ptread_h */
...@@ -295,17 +295,17 @@ typedef struct st_sort_info { ...@@ -295,17 +295,17 @@ typedef struct st_sort_info {
struct st_mi_check_param *param; struct st_mi_check_param *param;
enum data_file_type new_data_file_type; enum data_file_type new_data_file_type;
SORT_KEY_BLOCKS *key_block,*key_block_end; SORT_KEY_BLOCKS *key_block,*key_block_end;
uint key,find_length; uint key,find_length,real_key_length;
my_off_t pos,max_pos,filepos,start_recpos,filelength,dupp,buff_length; my_off_t pos,max_pos,filepos,start_recpos,filelength,dupp,buff_length;
ha_rows max_records; ha_rows max_records;
ulonglong unique[MI_MAX_KEY_SEG+1]; ulonglong unique[MI_MAX_KEY_SEG+1];
my_bool fix_datafile; my_bool fix_datafile;
char *record,*buff; char *record,*buff;
void *wordlist, *wordptr;
MI_KEYDEF *keyinfo; MI_KEYDEF *keyinfo;
MI_KEYSEG *keyseg; MI_KEYSEG *keyseg;
} SORT_INFO; } SORT_INFO;
typedef struct st_mi_check_param typedef struct st_mi_check_param
{ {
ulonglong auto_increment_value; ulonglong auto_increment_value;
......
...@@ -165,7 +165,7 @@ int my_net_write(NET *net,const char *packet,unsigned long len); ...@@ -165,7 +165,7 @@ int my_net_write(NET *net,const char *packet,unsigned long len);
int net_write_command(NET *net,unsigned char command,const char *packet, int net_write_command(NET *net,unsigned char command,const char *packet,
unsigned long len); unsigned long len);
int net_real_write(NET *net,const char *packet,unsigned long len); int net_real_write(NET *net,const char *packet,unsigned long len);
unsigned int my_net_read(NET *net); unsigned long my_net_read(NET *net);
struct rand_struct { struct rand_struct {
unsigned long seed1,seed2,max_value; unsigned long seed1,seed2,max_value;
......
...@@ -52,6 +52,10 @@ Vio* vio_new_win32pipe(HANDLE hPipe); ...@@ -52,6 +52,10 @@ Vio* vio_new_win32pipe(HANDLE hPipe);
#endif #endif
void vio_delete(Vio* vio); void vio_delete(Vio* vio);
#ifdef EMBEDDED_LIBRARY
void vio_reset(Vio *vio);
#endif
/* /*
* vio_read and vio_write should have the same semantics * vio_read and vio_write should have the same semantics
* as read(2) and write(2). * as read(2) and write(2).
......
This diff is collapsed.
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA
#
# This file is public domain and comes with NO WARRANTY of any kind
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
-DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
-DDATADIR="\"$(MYSQLDATAdir)\"" \
-DSHAREDIR="\"$(MYSQLSHAREdir)\""
INCLUDES = @MT_INCLUDES@ @bdb_includes@ -I$(srcdir)/../include -I../include \
-I$(srcdir)/.. -I$(top_srcdir) -I.. -I../sql -I../regex
## XXX: should we use client or server LDFLAGS for libmysqld?
LDADD = @CLIENT_EXTRA_LDFLAGS@ libmysqld.la
pkglib_LTLIBRARIES = libmysqld.la
libmysqld_la_SOURCES = libmysqld.c lib_sql.cc
libmysqlsources = errmsg.c get_password.c password.c
## XXX: we should not have to duplicate info from the sources list
libmysqlobjects = errmsg.lo get_password.lo password.lo
sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \
ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \
ha_myisam.cc ha_myisammrg.cc handler.cc hostname.cc init.cc \
item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
item_uniq.cc key.cc lock.cc log.cc log_event.cc md5.c \
mini_client.cc net_pkg.cc net_serv.cc opt_ft.cc opt_range.cc \
opt_sum.cc procedure.cc records.cc slave.cc sql_acl.cc \
sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
sql_crypt.cc sql_db.cc sql_delete.cc sql_insert.cc sql_lex.cc \
sql_list.cc sql_load.cc sql_manager.cc sql_map.cc sql_parse.cc \
sql_rename.cc sql_repl.cc sql_select.cc sql_show.cc \
sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
unireg.cc
## XXX: we should not have to duplicate info from the sources list
sqlobjects = convert.lo derror.lo field.lo field_conv.lo filesort.lo \
ha_berkeley.lo ha_heap.lo ha_isam.lo ha_isammrg.lo \
ha_myisam.lo ha_myisammrg.lo handler.lo hostname.lo init.lo \
item.lo item_buff.lo item_cmpfunc.lo item_create.lo \
item_func.lo item_strfunc.lo item_sum.lo item_timefunc.lo \
item_uniq.lo key.lo lock.lo log.lo log_event.lo md5.lo \
mini_client.lo net_pkg.lo net_serv.lo opt_ft.lo opt_range.lo \
opt_sum.lo procedure.lo records.lo slave.lo sql_acl.lo \
sql_analyse.lo sql_base.lo sql_cache.lo sql_class.lo \
sql_crypt.lo sql_db.lo sql_delete.lo sql_insert.lo sql_lex.lo \
sql_list.lo sql_load.lo sql_manager.lo sql_map.lo sql_parse.lo \
sql_rename.lo sql_repl.lo sql_select.lo sql_show.lo \
sql_string.lo sql_table.lo sql_test.lo sql_udf.lo \
sql_update.lo sql_yacc.lo table.lo thr_malloc.lo time.lo \
unireg.lo
EXTRA_DIST = lib_vio.c
# automake misses these
sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy
libmysqld_la_LIBADD = $(sqlobjects) $(libmysqlobjects)
## XXX: any time the client interface changes, we'll need to bump
## the version info for libmysqld; however, it's possible for the
## libmysqld interface to change without affecting the standard
## libmysqlclient interface. Should we make a separate version
## string for the two?
libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@
CLEANFILES = $(libmysqld_la_LIBADD) libmysqld.la
# This is called from the toplevel makefile
link_sources:
set -x; \
for f in $(sqlsources); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \
done; \
for f in $(libmysqlsources); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../libmysql/$$f $(srcdir)/$$f; \
done
clean-local:
rm -f `echo $(sqlsources) $(libmysqlsources) | sed "s;\.lo;.c;g"` \
$(top_srcdir)/linked_libmysqld_sources
# Don't update the files from bitkeeper
%::SCCS/s.%
LIBRARY (ONE_PROCESS VERSION) OF MYSQL CLIENT
Installation steps:
1) unpack mysql-3.23.27-beta.tar tarball source version (get from www.mysql.com.sg)
2) patch mysql-3.23.27-beta with lbver-3.23.27-beta.diff:
patch -p0 <lbver-3.23.27-beta.diff
3) cd mysql-3.23.27-beta
4) autoconf
7) ./configure --prefix=/usr/local/mysql --with-library-version
8) make
9) make install (should have the root privileges)
10)mkdir /usr/local/mysql/var (if not already)
15) cd ../client
19) ./mysql (start libarary version mysql)
mysql> create database db1;
mysql> use db1;
mysql> create table a123(i integer)
...... now you can work with library version....
LIBRARY VERSION DESIGN (EMBEDDED SERVER)
- The library version of MySQL server is the client library that contains embedded server.
- This client DLL has name : libmysqlclient_e (.la)
- The client application that supposed to use MySQL LV need to be rebuilt against libmysqlclient_e.la. The rebuild process is necessary, because libmysqlclient_e is a LIBTOOL object, which has the different LIBS list compared to the original libmysqlclient.la.
- The client and the server code run in the same process and the same thread;
- The server code is invoked when client writes the command to the net, and when connection is established;
/*
* Copyright (c) 2000
* SWsoft company
*
* This material is provided "as is", with absolutely no warranty expressed
* or implied. Any use is at your own risk.
*
* Permission to use or copy this software for any purpose is hereby granted
* without fee, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*
*/
/*
* Copyright (c) 2000
* SWsoft company
*
* This material is provided "as is", with absolutely no warranty expressed
* or implied. Any use is at your own risk.
*
* Permission to use or copy this software for any purpose is hereby granted
* without fee, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*
*/
/* Copy data from a textfile to table */
#include "mysql_priv.h"
#include <my_dir.h>
#include <m_ctype.h>
int
mysql_load_internal(THD * thd, sql_exchange * ex, TABLE_LIST * table_list,
List<Item> & fields, enum enum_duplicates handle_duplicates,
bool read_file_from_client, thr_lock_type lock_type);
int
mysql_load(THD * thd, sql_exchange * ex, TABLE_LIST * table_list,
List<Item> & fields, enum enum_duplicates handle_duplicates,
bool read_file_from_client, thr_lock_type lock_type)
{
printf("SWSOFT_MYSQL load: \n");
read_file_from_client = 0; //server is always in the same process
return mysql_load_internal(thd, ex, table_list, fields, handle_duplicates,
read_file_from_client, lock_type);
}
#define mysql_load mysql_load_internal
#include "../sql/sql_load.cc"
This diff is collapsed.
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
/*
Note that we can't have assertion on file descriptors; The reason for
this is that during mysql shutdown, another thread can close a file
we are working on. In this case we should just return read errors from
the file descriptior.
*/
#include <global.h>
#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
#include <errno.h>
#include <my_sys.h>
#include "mysql.h"
#include <violite.h>
#include <my_sys.h>
#include <my_net.h>
#include <m_string.h>
#include <dbug.h>
#include <assert.h>
#if defined(__EMX__)
#include <sys/ioctl.h>
#define ioctlsocket(A,B,C) ioctl((A),(B),(void *)(C),sizeof(*(C)))
#undef HAVE_FCNTL
#endif /* defined(__EMX__) */
#if defined(MSDOS) || defined(__WIN__)
#ifdef __WIN__
#undef errno
#undef EINTR
#undef EAGAIN
#define errno WSAGetLastError()
#define EINTR WSAEINTR
#define EAGAIN WSAEINPROGRESS
#endif /* __WIN__ */
#define O_NONBLOCK 1 /* For emulation of fcntl() */
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK EAGAIN
#endif
#ifndef __WIN__
#define HANDLE void *
#endif
struct st_vio
{
my_socket sd; /* my_socket - real or imaginary */
HANDLE hPipe;
my_bool localhost; /* Are we from localhost? */
int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
struct sockaddr_in local; /* Local internet address */
struct sockaddr_in remote; /* Remote internet address */
enum enum_vio_type type; /* Type of connection */
char desc[30]; /* String description */
/* #ifdef EMBEDDED_LIBRARY */
/* void *dest_net; */
void *dest_thd;
char *packets, **last_packet;
char *where_in_packet, *end_of_packet;
my_bool reading;
MEM_ROOT root;
/* #endif */
};
/* Initialize the communication buffer */
Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
{
Vio * vio = NULL;
vio = (Vio *) my_malloc (sizeof(*vio),MYF(MY_WME|MY_ZEROFILL));
if (vio)
{
init_alloc_root(&vio->root, 8192, 1024);
vio->root.min_malloc = sizeof(char *) + 4;
vio->last_packet = &vio->packets;
}
return (vio);
}
#ifdef __WIN__
Vio *vio_new_win32pipe(HANDLE hPipe)
{
return (NULL);
}
#endif
void vio_delete(Vio * vio)
{
if (vio)
{
if (vio->type != VIO_CLOSED) vio_close(vio);
free_root(&vio->root, MYF(0));
my_free((gptr)vio, MYF(0));
}
}
void vio_reset(Vio *vio)
{
free_root(&vio->root, MYF(MY_KEEP_PREALLOC));
vio->packets = vio->where_in_packet = vio->end_of_packet = 0;
vio->last_packet = &vio->packets;
}
int vio_errno(Vio *vio __attribute__((unused)))
{
return errno; /* On Win32 this mapped to WSAGetLastError() */
}
int vio_read(Vio * vio, gptr buf, int size)
{
vio->reading = 1;
if (vio->where_in_packet >= vio->end_of_packet)
{
dbug_assert(vio->packets);
vio->where_in_packet = vio->packets + sizeof(char *) + 4;
vio->end_of_packet = vio->where_in_packet +
uint4korr(vio->packets + sizeof(char *));
vio->packets = *(char **)vio->packets;
}
memcpy(buf, vio->where_in_packet, size);
vio->where_in_packet += size;
return (size);
}
int vio_write(Vio * vio, const gptr buf, int size)
{
char *packet;
if (vio->reading)
{
vio->reading = 0;
vio_reset(vio);
}
if ((packet = alloc_root(&vio->root, sizeof(char*) + 4 + size)))
{
*vio->last_packet = packet;
vio->last_packet = (char **)packet;
*((char **)packet) = 0; /* safety */
packet += sizeof(char *);
int4store(packet, size);
memcpy(packet + 4, buf, size);
}
else
size=0;
return (size);
}
int vio_blocking(Vio * vio, my_bool set_blocking_mode)
{
int r=0;
return (r);
}
my_bool
vio_is_blocking(Vio * vio)
{
my_bool r=0;
return(r);
}
int vio_fastsend(Vio * vio)
{
int r=0;
return(r);
}
int vio_keepalive(Vio* vio, my_bool set_keep_alive)
{
int r=0;
return (r);
}
my_bool
vio_should_retry(Vio * vio __attribute__((unused)))
{
int en = errno;
return en == EAGAIN || en == EINTR || en == EWOULDBLOCK;
}
int vio_close(Vio * vio)
{
int r=0;
return(r);
}
const char *vio_description(Vio * vio)
{
return "embedded vio";
}
enum enum_vio_type vio_type(Vio* vio)
{
return VIO_CLOSED;
}
my_socket vio_fd(Vio* vio)
{
return 0;
}
my_bool vio_peer_addr(Vio * vio, char *buf)
{
return(0);
}
void vio_in_addr(Vio *vio, struct in_addr *in)
{
}
#endif /* HAVE_VIO */
This diff is collapsed.
...@@ -25,13 +25,14 @@ bin_PROGRAMS = myisamchk myisamlog myisampack ...@@ -25,13 +25,14 @@ bin_PROGRAMS = myisamchk myisamlog myisampack
myisamchk_DEPENDENCIES= $(LIBRARIES) myisamchk_DEPENDENCIES= $(LIBRARIES)
myisamlog_DEPENDENCIES= $(LIBRARIES) myisamlog_DEPENDENCIES= $(LIBRARIES)
myisampack_DEPENDENCIES=$(LIBRARIES) myisampack_DEPENDENCIES=$(LIBRARIES)
noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 ft_test1 ft_eval noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 ft_test1 ft_eval ft_dump
noinst_HEADERS = myisamdef.h fulltext.h ftdefs.h ft_test1.h ft_eval.h noinst_HEADERS = myisamdef.h fulltext.h ftdefs.h ft_test1.h ft_eval.h
mi_test1_DEPENDENCIES= $(LIBRARIES) mi_test1_DEPENDENCIES= $(LIBRARIES)
mi_test2_DEPENDENCIES= $(LIBRARIES) mi_test2_DEPENDENCIES= $(LIBRARIES)
mi_test3_DEPENDENCIES= $(LIBRARIES) mi_test3_DEPENDENCIES= $(LIBRARIES)
ft_test1_DEPENDENCIES= $(LIBRARIES) ft_test1_DEPENDENCIES= $(LIBRARIES)
ft_eval_DEPENDENCIES= $(LIBRARIES) ft_eval_DEPENDENCIES= $(LIBRARIES)
ft_dump_DEPENDENCIES= $(LIBRARIES)
libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
mi_rnext.c mi_rnext_same.c \ mi_rnext.c mi_rnext_same.c \
mi_search.c mi_page.c mi_key.c mi_locking.c \ mi_search.c mi_page.c mi_key.c mi_locking.c \
...@@ -45,7 +46,7 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \ ...@@ -45,7 +46,7 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
mi_changed.c mi_static.c mi_delete_all.c \ mi_changed.c mi_static.c mi_delete_all.c \
mi_delete_table.c mi_rename.c mi_check.c \ mi_delete_table.c mi_rename.c mi_check.c \
ft_parser.c ft_search.c ft_stopwords.c ft_static.c \ ft_parser.c ft_search.c ft_stopwords.c ft_static.c \
ft_update.c sort.c ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c
CLEANFILES = test?.MY? FT?.MY? isam.log mi_test_all CLEANFILES = test?.MY? FT?.MY? isam.log mi_test_all
DEFS = -DMAP_TO_USE_RAID DEFS = -DMAP_TO_USE_RAID
# Omit dependency for ../mit-pthreads/include/sys that only exits if # Omit dependency for ../mit-pthreads/include/sys that only exits if
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either 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 */
/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
#include "ftdefs.h"
/* search with boolean queries */
typedef struct st_all_in_one {
MI_INFO *info;
uint keynr;
uchar *keybuff;
MI_KEYDEF *keyinfo;
my_off_t key_root;
TREE dtree;
byte *start, *end;
uint total_yes, total_no;
} ALL_IN_ONE;
typedef struct st_ft_superdoc {
FT_DOC doc;
//FT_WORD *word_ptr;
//double tmp_weight;
uint yes;
uint no;
uint wno;
ALL_IN_ONE *aio;
} FT_SUPERDOC;
static int FT_SUPERDOC_cmp(FT_SUPERDOC *p1, FT_SUPERDOC *p2)
{
if (p1->doc.dpos < p2->doc.dpos)
return -1;
if (p1->doc.dpos == p2->doc.dpos)
return 0;
return 1;
}
static int walk_and_copy(FT_SUPERDOC *from,
uint32 count __attribute__((unused)), FT_DOC **to)
{
if (from->yes == from->aio->total_yes && !from->no)
{
(*to)->dpos=from->doc.dpos;
(*to)->weight=from->doc.weight;
(*to)++;
}
return 0;
}
static double _wghts[11]={
0.131687242798354,
0.197530864197531,
0.296296296296296,
0.444444444444444,
0.666666666666667,
1.000000000000000,
1.500000000000000,
2.250000000000000,
3.375000000000000,
5.062500000000000,
7.593750000000000};
static double *wghts=_wghts+5; // wghts[i] = 1.5**i
static double _nwghts[11]={
-0.065843621399177,
-0.098765432098766,
-0.148148148148148,
-0.222222222222222,
-0.333333333333334,
-0.500000000000000,
-0.750000000000000,
-1.125000000000000,
-1.687500000000000,
-2.531250000000000,
-3.796875000000000};
static double *nwghts=_nwghts+5; // nwghts[i] = -0.5*1.5**i
int do_boolean(ALL_IN_ONE *aio, uint nested,
int yesno, int plusminus, bool pmsign)
{
int r, res;
uint keylen, wno;
FT_SUPERDOC sdoc, *sptr;
TREE_ELEMENT *selem;
FT_WORD w;
FTB_PARAM param;
#ifdef EVAL_RUN
return 1;
#endif /* EVAL_RUN */
param.prev=' ';
for(wno=1; res=ft_get_word(&aio->start,aio->end,&w,&param); wno++)
{
r=plusminus+param.plusminus;
if (param.pmsign^pmsign)
w.weight=nwghts[(r>5)?5:((r<-5)?-5:r)];
else
w.weight=wghts[(r>5)?5:((r<-5)?-5:r)];
if (param.yesno>0) aio->total_yes++;
if (param.yesno<0) aio->total_no++;
switch (res) {
case FTB_LBR: // (
//if (do_boolean(aio,nested+1,my_yesno,plusminus+my_plusminus))
// return 1;
// ???
break;
case 1: // word
keylen=_ft_make_key(aio->info,aio->keynr,(char*) aio->keybuff,&w,0);
keylen-=HA_FT_WLEN;
r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
while (!r)
{
if (param.trunc)
r=_mi_compare_text(default_charset_info,
aio->info->lastkey+1,keylen-1,
aio->keybuff+1,keylen-1,0);
else
r=_mi_compare_text(default_charset_info,
aio->info->lastkey,keylen,
aio->keybuff,keylen,0);
if (r) break;
sdoc.doc.dpos=aio->info->lastpos;
/* saving document matched into dtree */
if (!(selem=tree_insert(&aio->dtree, &sdoc, 0))) return 1;
sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
if (selem->count==1) /* document's first match */
{
sptr->yes=sptr->no=sptr->doc.weight=0;
sptr->aio=aio;
sptr->wno=0;
}
if (sptr->wno != wno)
{
if (param.yesno>0) sptr->yes++;
if (param.yesno<0) sptr->no++;
sptr->wno=wno;
}
sptr->doc.weight+=w.weight;
if (_mi_test_if_changed(aio->info) == 0)
r=_mi_search_next(aio->info, aio->keyinfo, aio->info->lastkey,
aio->info->lastkey_length, SEARCH_BIGGER,
aio->key_root);
else
r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
aio->info->lastkey_length, SEARCH_BIGGER,
aio->key_root);
}
break;
case FTB_RBR: // )
break;
}
}
return 0;
}
FT_DOCLIST *ft_boolean_search(MI_INFO *info, uint keynr, byte *query,
uint query_len)
{
ALL_IN_ONE aio;
FT_DOC *dptr;
FT_DOCLIST *dlist=NULL;
aio.info=info;
aio.keynr=keynr;
aio.keybuff=aio.info->lastkey+aio.info->s->base.max_key_length;
aio.keyinfo=aio.info->s->keyinfo+keynr;
aio.key_root=aio.info->s->state.key_root[keynr];
aio.start=query;
aio.end=query+query_len;
aio.total_yes=aio.total_no=0;
init_tree(&aio.dtree,0,sizeof(FT_SUPERDOC),(qsort_cmp)&FT_SUPERDOC_cmp,0,
NULL);
if (do_boolean(&aio,0,0,0,0))
goto err;
dlist=(FT_DOCLIST *)my_malloc(sizeof(FT_DOCLIST)+sizeof(FT_DOC)*(aio.dtree.elements_in_tree-1),MYF(0));
if(!dlist)
goto err;
dlist->ndocs=aio.dtree.elements_in_tree;
dlist->curdoc=-1;
dlist->info=aio.info;
dptr=dlist->doc;
tree_walk(&aio.dtree, (tree_walk_action)&walk_and_copy, &dptr, left_root_right);
dlist->ndocs=dptr - dlist->doc;
err:
delete_tree(&aio.dtree);
return dlist;
}
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either 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 */
/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
#include "ftdefs.h"
static void get_options(int argc,char *argv[]);
static void usage(char *argv[]);
static void complain(int val);
static int count=0, stats=0, dump=0, verbose=0;
static char *query=NULL;
#define MAX (MAX_WORD_LEN+10)
#define HOW_OFTEN_TO_WRITE 1000
int main(int argc,char *argv[])
{
int error=0;
uint keylen, inx, doc_cnt;
float weight;
double gws, min_gws, avg_gws=0;
MI_INFO *info;
char buf[MAX], buf2[MAX], buf_maxlen[MAX], buf_min_gws[MAX], *s;
ulong total=0, maxlen=0, uniq=0, max_doc_cnt=0;
#ifdef EVAL_RUN
uint cnt;
double sum, sum2, suml;
#endif /* EVAL_RUN */
struct { MI_INFO *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */
MY_INIT(argv[0]);
get_options(argc,argv);
if (count || dump)
verbose=0;
else
stats=1;
if (verbose)
setbuf(stdout,NULL);
if (argc-optind < 2)
usage(argv);
if (!(info=mi_open(argv[optind],2,HA_OPEN_ABORT_IF_LOCKED)))
goto err;
inx=atoi(argv[optind+1]);
*buf2=0;
aio->info=info;
if ((inx >= info->s->base.keys) || !(info->s->keyinfo[inx].flag & HA_FULLTEXT))
{
printf("Key %d in table %s is not a FULLTEXT key\n", inx, info->filename);
goto err;
}
if (query)
{
FT_DOCLIST *result;
int i;
ft_init_stopwords(ft_precompiled_stopwords);
result=ft_init_search(info,inx,query,strlen(query),1);
if(!result)
goto err;
if (verbose)
printf("%d rows matched\n",result->ndocs);
for(i=0 ; i<result->ndocs ; i++)
printf("%9qx %20.7f\n",result->doc[i].dpos,result->doc[i].weight);
ft_close_search(result);
}
else
{
info->lastpos= HA_OFFSET_ERROR;
info->update|= HA_STATE_PREV_FOUND;
while (!(error=mi_rnext(info,NULL,inx)))
{
keylen=*(info->lastkey);
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
#ifdef EVAL_RUN
mi_float4get(weight,info->lastkey+keylen+2);
#else /* EVAL_RUN */
mi_float4get(weight,info->lastkey+keylen+1);
#endif /* EVAL_RUN */
#else
#error
#endif
#ifdef EVAL_RUN
cnt=*(byte *)(info->lastkey+keylen);
#endif /* EVAL_RUN */
snprintf(buf,MAX,"%.*s",keylen,info->lastkey+1);
for (s=buf;*s;s++) *s=tolower(*s);
total++;
if (count || stats)
{
doc_cnt++;
#ifdef EVAL_RUN
sum +=cnt;
sum2+=cnt*cnt;
suml+=cnt*log(cnt);
#endif /* EVAL_RUN */
if (strcmp(buf, buf2))
{
if (*buf2)
{
uniq++;
avg_gws+=gws=GWS_IN_USE;
if (count)
printf("%9u %20.7f %s\n",doc_cnt,gws,buf2);
if (maxlen<keylen)
{
maxlen=keylen;
strcpy(buf_maxlen, buf2);
}
if (max_doc_cnt < doc_cnt)
{
max_doc_cnt=doc_cnt;
strcpy(buf_min_gws, buf2);
min_gws=gws;
}
}
strcpy(buf2, buf);
#ifdef EVAL_RUN
sum=sum2=suml=
#endif /* EVAL_RUN */
doc_cnt=0;
}
}
if (dump)
printf("%9qx %20.7f %s\n",info->lastpos,weight,buf);
if(verbose && (total%HOW_OFTEN_TO_WRITE)==0)
printf("%10ld\r",total);
}
if (stats)
printf("Total rows: %qu\nTotal words: %lu\n"
"Unique words: %lu\nLongest word: %lu chars (%s)\n"
"Average global weight: %f\n"
"Most common word: %lu times, weight: %f (%s)\n",
(ulonglong)info->state->records, total, uniq, maxlen, buf_maxlen,
avg_gws/uniq, max_doc_cnt, min_gws, buf_min_gws);
}
err:
if (error && error != HA_ERR_END_OF_FILE)
printf("got error %d\n",my_errno);
if (info)
mi_close(info);
return 0;
}
const char *options="dscve:h";
static void get_options(int argc, char *argv[])
{
int c;
while ((c=getopt(argc,argv,options)) != -1)
{
switch(c) {
case 'd': dump=1; complain(count || query); break;
case 's': stats=1; complain(query!=0); break;
case 'v': verbose=1; break;
case 'c': count=1; complain(dump || query); break;
case 'e': query=my_strdup(optarg,MYF(MY_FAE)); complain(dump || count || stats); break;
case '?':
case 'h':
default:
usage(argv);
}
}
return;
} /* get options */
static void usage(char *argv[])
{
printf("Use: %s [-%s] <table_name> <key_no>\n", *argv, options);
exit(1);
}
static void complain(int val) /* Kinda assert :-) */
{
if (val)
{
printf("You cannot use these options together!\n");
exit(1);
}
}
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either 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 */
/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
#include "ftdefs.h"
/* search with natural language queries */
typedef struct st_all_in_one {
MI_INFO *info;
uint keynr;
uchar *keybuff;
MI_KEYDEF *keyinfo;
my_off_t key_root;
TREE dtree;
} ALL_IN_ONE;
typedef struct st_ft_superdoc {
FT_DOC doc;
FT_WORD *word_ptr;
double tmp_weight;
} FT_SUPERDOC;
static int FT_SUPERDOC_cmp(FT_SUPERDOC *p1, FT_SUPERDOC *p2)
{
if (p1->doc.dpos < p2->doc.dpos)
return -1;
if (p1->doc.dpos == p2->doc.dpos)
return 0;
return 1;
}
static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
{
uint keylen, r, doc_cnt;
#ifdef EVAL_RUN
uint cnt;
double sum, sum2, suml;
#endif /* EVAL_RUN */
FT_SUPERDOC sdoc, *sptr;
TREE_ELEMENT *selem;
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
float tmp_weight;
#else
#error
#endif
word->weight=LWS_FOR_QUERY;
keylen=_ft_make_key(aio->info,aio->keynr,(char*) aio->keybuff,word,0);
#ifdef EVAL_RUN
keylen-=1+HA_FT_WLEN;
#else /* EVAL_RUN */
keylen-=HA_FT_WLEN;
#endif /* EVAL_RUN */
#ifdef EVAL_RUN
sum=sum2=suml=
#endif /* EVAL_RUN */
doc_cnt=0;
r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
while(!r)
{
if (_mi_compare_text(default_charset_info,
aio->info->lastkey,keylen,
aio->keybuff,keylen,0)) break;
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
#ifdef EVAL_RUN
mi_float4get(tmp_weight,aio->info->lastkey+keylen+1);
#else /* EVAL_RUN */
mi_float4get(tmp_weight,aio->info->lastkey+keylen);
#endif /* EVAL_RUN */
#else
#error
#endif
if(tmp_weight==0) return doc_cnt; /* stopword, doc_cnt should be 0 */
#ifdef EVAL_RUN
cnt=*(byte *)(aio->info->lastkey+keylen);
#endif /* EVAL_RUN */
sdoc.doc.dpos=aio->info->lastpos;
/* saving document matched into dtree */
if(!(selem=tree_insert(&aio->dtree, &sdoc, 0))) return 1;
sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
if(selem->count==1) /* document's first match */
sptr->doc.weight=0;
else
sptr->doc.weight+=sptr->tmp_weight*sptr->word_ptr->weight;
sptr->word_ptr=word;
sptr->tmp_weight=tmp_weight;
doc_cnt++;
#ifdef EVAL_RUN
sum +=cnt;
sum2+=cnt*cnt;
suml+=cnt*log(cnt);
#endif /* EVAL_RUN */
if (_mi_test_if_changed(aio->info) == 0)
r=_mi_search_next(aio->info, aio->keyinfo, aio->info->lastkey,
aio->info->lastkey_length, SEARCH_BIGGER,
aio->key_root);
else
r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
aio->info->lastkey_length, SEARCH_BIGGER,
aio->key_root);
}
if(doc_cnt) {
word->weight*=GWS_IN_USE;
if(word->weight < 0) word->weight=0;
}
return 0;
}
static int walk_and_copy(FT_SUPERDOC *from,
uint32 count __attribute__((unused)), FT_DOC **to)
{
from->doc.weight+=from->tmp_weight*from->word_ptr->weight;
(*to)->dpos=from->doc.dpos;
(*to)->weight=from->doc.weight;
(*to)++;
return 0;
}
FT_DOCLIST *ft_nlq_search(MI_INFO *info, uint keynr, byte *query,
uint query_len)
{
TREE *wtree, allocated_wtree;
ALL_IN_ONE aio;
FT_DOC *dptr;
FT_DOCLIST *dlist=NULL;
aio.info=info;
aio.keynr=keynr;
aio.keybuff=aio.info->lastkey+aio.info->s->base.max_key_length;
aio.keyinfo=aio.info->s->keyinfo+keynr;
aio.key_root=aio.info->s->state.key_root[keynr];
bzero(&allocated_wtree,sizeof(allocated_wtree));
init_tree(&aio.dtree,0,sizeof(FT_SUPERDOC),(qsort_cmp)&FT_SUPERDOC_cmp,0,
NULL);
if(!(wtree=ft_parse(&allocated_wtree,query,query_len)))
return NULL;
if(tree_walk(wtree, (tree_walk_action)&walk_and_match, &aio,
left_root_right))
goto err;
dlist=(FT_DOCLIST *)my_malloc(sizeof(FT_DOCLIST)+sizeof(FT_DOC)*(aio.dtree.elements_in_tree-1),MYF(0));
if(!dlist)
goto err;
dlist->ndocs=aio.dtree.elements_in_tree;
dlist->curdoc=-1;
dlist->info=aio.info;
dptr=dlist->doc;
tree_walk(&aio.dtree, (tree_walk_action)&walk_and_copy, &dptr, left_root_right);
err:
delete_tree(wtree);
delete_tree(&aio.dtree);
return dlist;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -625,15 +625,20 @@ static void setup_key_functions(register MI_KEYDEF *keyinfo) ...@@ -625,15 +625,20 @@ static void setup_key_functions(register MI_KEYDEF *keyinfo)
} }
else if (keyinfo->flag & HA_VAR_LENGTH_KEY) else if (keyinfo->flag & HA_VAR_LENGTH_KEY)
{ {
keyinfo->bin_search=_mi_seq_search;
keyinfo->get_key= _mi_get_pack_key; keyinfo->get_key= _mi_get_pack_key;
if (keyinfo->seg[0].flag & HA_PACK_KEY) if (keyinfo->seg[0].flag & HA_PACK_KEY)
{ /* Prefix compression */ { /* Prefix compression */
if (!keyinfo->seg->charset || use_strcoll(keyinfo->seg->charset) ||
(keyinfo->seg->flag & HA_NULL_PART))
keyinfo->bin_search=_mi_seq_search;
else
keyinfo->bin_search=_mi_prefix_search;
keyinfo->pack_key=_mi_calc_var_pack_key_length; keyinfo->pack_key=_mi_calc_var_pack_key_length;
keyinfo->store_key=_mi_store_var_pack_key; keyinfo->store_key=_mi_store_var_pack_key;
} }
else else
{ {
keyinfo->bin_search=_mi_seq_search;
keyinfo->pack_key=_mi_calc_var_key_length; /* Variable length key */ keyinfo->pack_key=_mi_calc_var_key_length; /* Variable length key */
keyinfo->store_key=_mi_store_static_key; keyinfo->store_key=_mi_store_static_key;
} }
......
This diff is collapsed.
...@@ -98,9 +98,7 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) ...@@ -98,9 +98,7 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
if ((int) i == info->lastinx) if ((int) i == info->lastinx)
key_changed|=HA_STATE_WRITTEN; key_changed|=HA_STATE_WRITTEN;
changed|=((ulonglong) 1 << i); changed|=((ulonglong) 1 << i);
if (_mi_ft_del(info,i,(char*) old_key,oldrec,pos)) if (_mi_ft_update(info,i,(char*) old_key,oldrec,newrec,pos))
goto err;
if (_mi_ft_add(info,i,(char*) new_key,newrec,pos))
goto err; goto err;
} }
} }
......
...@@ -473,6 +473,9 @@ extern int _mi_bin_search(struct st_myisam_info *info,MI_KEYDEF *keyinfo, ...@@ -473,6 +473,9 @@ extern int _mi_bin_search(struct st_myisam_info *info,MI_KEYDEF *keyinfo,
extern int _mi_seq_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page, extern int _mi_seq_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page,
uchar *key,uint key_len,uint comp_flag, uchar *key,uint key_len,uint comp_flag,
uchar **ret_pos,uchar *buff, my_bool *was_last_key); uchar **ret_pos,uchar *buff, my_bool *was_last_key);
extern int _mi_prefix_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page,
uchar *key,uint key_len,uint comp_flag,
uchar **ret_pos,uchar *buff, my_bool *was_last_key);
extern int _mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint , extern int _mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint ,
my_bool); my_bool);
extern my_off_t _mi_kpos(uint nod_flag,uchar *after_key); extern my_off_t _mi_kpos(uint nod_flag,uchar *after_key);
...@@ -640,6 +643,7 @@ int mi_open_keyfile(MYISAM_SHARE *share); ...@@ -640,6 +643,7 @@ int mi_open_keyfile(MYISAM_SHARE *share);
void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...)); void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...));
void mi_check_print_warning _VARARGS((MI_CHECK *param, const char *fmt,...)); void mi_check_print_warning _VARARGS((MI_CHECK *param, const char *fmt,...));
void mi_check_print_info _VARARGS((MI_CHECK *param, const char *fmt,...)); void mi_check_print_info _VARARGS((MI_CHECK *param, const char *fmt,...));
int flush_pending_blocks(MI_CHECK *param);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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