summaryrefslogtreecommitdiff
path: root/myisammrg
diff options
context:
space:
mode:
authorunknown <serg@infomag.ape.relarn.ru>2000-08-14 15:27:19 +0400
committerunknown <serg@infomag.ape.relarn.ru>2000-08-14 15:27:19 +0400
commit24772d99999d128f77626cb1c4a19dbcb29b43b2 (patch)
tree290f97643db41800f2922e6143b2a89e93d5476d /myisammrg
parent99110483b2271095dd8b2cb655e3a054f6f7c5a5 (diff)
downloadmariadb-git-24772d99999d128f77626cb1c4a19dbcb29b43b2.tar.gz
PART I: Keys support for MyMERGE tables
myisammrg/ | Makefile.am | mymrgdef.h | support for keys myrg_open.c | & myrg_queue.c | bugfixes myrg_rfirst.c | myrg_rkey.c | myrg_rlast.c | myrg_rnext.c | myrg_rprev.c | myrg_rrnd.c | include/myisammrg.h | rkey/rnext/etc prototyped sql/ | ha_myisammrg.cc | support for keys ha_myisammrg.h | myisam/ | mi_rkey.c | buf==NULL extension, _mi_rkey() mi_rnext.c | mi_rprev.c | include/queues.h | reinit_queue() - same as init_queue, but w/o malloc mysys/queues.c | PART II: Miscellaneous myisam/common_words | deleted (looks like I checked it in by mistake) some files (like acconfig.h, Makefile.am, COPYING.LIB, etc) | Change mode to -rw-r--r-- (by `chmod a-x ') include/queues.h: Initial, from cvs myisammrg/Makefile.am: Initial, from cvs myisammrg/mymrgdef.h: Initial, from cvs myisammrg/myrg_open.c: Initial, from cvs mysys/queues.c: Initial, from cvs BitKeeper/deleted/.del-common_words: ***MISSING WEAVE*** Makefile.am: Change mode to -rw-r--r-- include/mysql_version.h.in: Change mode to -rw-r--r-- libmysql/acconfig.h: ***MISSING WEAVE*** mysys/COPYING.LIB: Change mode to -rw-r--r-- sql/item_uniq.cc: Change mode to -rw-r--r-- sql/item_uniq.h: Change mode to -rw-r--r-- sql/share/Makefile.am: Change mode to -rw-r--r-- strings/ChangeLog: Change mode to -rw-r--r-- support-files/Makefile.am: Change mode to -rw-r--r-- myisam/mi_rkey.c: looks like rkey/rnext for MyMERGE is working myisam/mi_rnext.c: looks like rkey/rnext for MyMERGE is working myisammrg/myrg_queue.c: looks like rkey/rnext for MyMERGE is working myisammrg/myrg_rkey.c: looks like rkey/rnext for MyMERGE is working myisammrg/myrg_rnext.c: probably, works myisammrg/myrg_rprev.c: probably, works include/myisammrg.h: rkey/rnext/etc prototyped myisam/mi_rprev.c: buf==NULL, extension sql/ha_myisammrg.cc: support for keys sql/ha_myisammrg.h: support for keys myisammrg/myrg_rrnd.c: ORDER BY didn't work acconfig.h: Change mode to -rw-r--r--
Diffstat (limited to 'myisammrg')
-rw-r--r--myisammrg/Makefile.am5
-rw-r--r--myisammrg/mymrgdef.h3
-rw-r--r--myisammrg/myrg_open.c1
-rw-r--r--myisammrg/myrg_queue.c52
-rw-r--r--myisammrg/myrg_rfirst.c49
-rw-r--r--myisammrg/myrg_rkey.c89
-rw-r--r--myisammrg/myrg_rlast.c50
-rw-r--r--myisammrg/myrg_rnext.c75
-rw-r--r--myisammrg/myrg_rprev.c76
-rw-r--r--myisammrg/myrg_rrnd.c2
10 files changed, 399 insertions, 3 deletions
diff --git a/myisammrg/Makefile.am b/myisammrg/Makefile.am
index e51b9b52faf..020cd567ec9 100644
--- a/myisammrg/Makefile.am
+++ b/myisammrg/Makefile.am
@@ -19,8 +19,9 @@ pkglib_LIBRARIES = libmyisammrg.a
noinst_HEADERS = mymrgdef.h
libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
myrg_rrnd.c myrg_update.c myrg_delete.c myrg_rsame.c \
- myrg_panic.c myrg_close.c myrg_create.c myrg_static.c
-
+ myrg_panic.c myrg_close.c myrg_create.c myrg_static.c \
+ myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \
+ myrg_rprev.c myrg_queue.c
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 \
diff --git a/myisammrg/mymrgdef.h b/myisammrg/mymrgdef.h
index 794104fd8c8..945a415525f 100644
--- a/myisammrg/mymrgdef.h
+++ b/myisammrg/mymrgdef.h
@@ -27,3 +27,6 @@ extern LIST *myrg_open_list;
#ifdef THREAD
extern pthread_mutex_t THR_LOCK_open;
#endif
+
+int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag);
+
diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c
index 0606e0d7d88..d3bb0b4e7b6 100644
--- a/myisammrg/myrg_open.c
+++ b/myisammrg/myrg_open.c
@@ -119,6 +119,7 @@ int handle_locking;
pthread_mutex_lock(&THR_LOCK_open);
myrg_open_list=list_add(myrg_open_list,&m_info->open_list);
pthread_mutex_unlock(&THR_LOCK_open);
+ m_info->by_key.root=0;
DBUG_RETURN(m_info);
err:
diff --git a/myisammrg/myrg_queue.c b/myisammrg/myrg_queue.c
new file mode 100644
index 00000000000..47ccdce1554
--- /dev/null
+++ b/myisammrg/myrg_queue.c
@@ -0,0 +1,52 @@
+/* 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 */
+
+/* Read record based on a key */
+
+#include "mymrgdef.h"
+
+static int queue_key_cmp(void *keyseg, byte *a, byte *b)
+{
+ MI_INFO *aa=((MYRG_TABLE *)a)->table;
+ MI_INFO *bb=((MYRG_TABLE *)b)->table;
+ uint not_used;
+
+ return (_mi_key_cmp((MI_KEYSEG *)keyseg, aa->lastkey, bb->lastkey,
+ USE_WHOLE_KEY, SEARCH_FIND, &not_used));
+} /* queue_key_cmp */
+
+int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
+{
+ QUEUE *q=&(info->by_key);
+
+ if (!q->root)
+ {
+ if (init_queue(q,info->tables, 0,
+ (myisam_read_vec[search_flag]==SEARCH_SMALLER),
+ queue_key_cmp,
+ info->open_tables->table->s->keyinfo[inx].seg))
+ return my_errno;
+ }
+ else
+ {
+ if (reinit_queue(q,info->tables, 0,
+ (myisam_read_vec[search_flag]==SEARCH_SMALLER),
+ queue_key_cmp,
+ info->open_tables->table->s->keyinfo[inx].seg))
+ return my_errno;
+ }
+}
+
diff --git a/myisammrg/myrg_rfirst.c b/myisammrg/myrg_rfirst.c
new file mode 100644
index 00000000000..f344eb2318f
--- /dev/null
+++ b/myisammrg/myrg_rfirst.c
@@ -0,0 +1,49 @@
+/* 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 "mymrgdef.h"
+
+ /* Read first row through a specfic key */
+
+int myrg_rfirst(MYRG_INFO *info, byte *buf, int inx)
+{
+ MYRG_TABLE *table;
+ MI_INFO *mi;
+ int err;
+
+ if (_myrg_init_queue(info,inx,HA_READ_KEY_OR_NEXT))
+ return my_errno;
+
+ for (table=info->open_tables ; table < info->end_table ; table++)
+ {
+ err=mi_rfirst(table->table,NULL,inx);
+ info->last_used_table=table;
+
+ if (err == HA_ERR_END_OF_FILE)
+ continue;
+ if (err)
+ return err;
+
+ /* adding to queue */
+ queue_insert(&(info->by_key),(byte *)table);
+ }
+
+ if (!info->by_key.elements)
+ return HA_ERR_END_OF_FILE;
+
+ mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
+ return mi_rrnd(mi,buf,mi->lastpos);
+}
diff --git a/myisammrg/myrg_rkey.c b/myisammrg/myrg_rkey.c
new file mode 100644
index 00000000000..2f4cfb60068
--- /dev/null
+++ b/myisammrg/myrg_rkey.c
@@ -0,0 +1,89 @@
+/* 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 */
+
+/* Read record based on a key */
+
+#include "mymrgdef.h"
+
+/* todo: we could store some additional info to speedup lookups:
+ column (key, keyseg) can be constant per table
+ it can also be increasing (table1.val > table2.val > ...),
+ or decreasing, <=, >=, etc.
+ SerG
+*/
+
+int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key,
+ uint key_len, enum ha_rkey_function search_flag)
+{
+ uchar *key_buff;
+ uint pack_key_length;
+ MYRG_TABLE *table;
+ MI_INFO *mi;
+ int err;
+ byte *buf=((search_flag == HA_READ_KEY_EXACT)?record:0);
+
+ if (_myrg_init_queue(info,inx,search_flag))
+ return my_errno;
+
+ for (table=info->open_tables ; table < info->end_table ; table++)
+ {
+ mi=table->table;
+
+ if (table == info->open_tables)
+ {
+ err=mi_rkey(mi,buf,inx,key,key_len,search_flag);
+ key_buff=mi->lastkey+mi->s->base.max_key_length;
+ pack_key_length=mi->last_rkey_length;
+ }
+ else
+ {
+ err=_mi_rkey(mi,buf,inx,key_buff,pack_key_length,search_flag,FALSE);
+ }
+ info->last_used_table=table;
+
+ if (err == HA_ERR_KEY_NOT_FOUND)
+ continue;
+ if (err)
+ return err;
+
+ /* adding to queue */
+ queue_insert(&(info->by_key),(byte *)table);
+
+ /* if looking for KEY_EXACT, return first matched now */
+ if (buf)
+ {
+ info->current_table=table;
+ return 0;
+ }
+ }
+
+ if (!info->by_key.elements)
+ return HA_ERR_KEY_NOT_FOUND;
+
+ mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
+ return mi_rrnd(mi,record,mi->lastpos);
+}
+
+/*
+ * HA_READ_KEY_EXACT => SEARCH_BIGGER
+ * HA_READ_KEY_OR_NEXT => SEARCH_BIGGER
+ * HA_READ_AFTER_KEY => SEARCH_BIGGER
+ * HA_READ_PREFIX => SEARCH_BIGGER
+ * HA_READ_KEY_OR_PREV => SEARCH_SMALLER
+ * HA_READ_BEFORE_KEY => SEARCH_SMALLER
+ * HA_READ_PREFIX_LAST => SEARCH_SMALLER
+ */
+
diff --git a/myisammrg/myrg_rlast.c b/myisammrg/myrg_rlast.c
new file mode 100644
index 00000000000..ab7aacda716
--- /dev/null
+++ b/myisammrg/myrg_rlast.c
@@ -0,0 +1,50 @@
+/* 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 "mymrgdef.h"
+
+ /* Read last row with the same key as the previous read. */
+
+int myrg_rlast(MYRG_INFO *info, byte *buf, int inx)
+{
+ MYRG_TABLE *table;
+ MI_INFO *mi;
+ int err;
+
+ if (_myrg_init_queue(info,inx,HA_READ_KEY_OR_PREV))
+ return my_errno;
+
+ for (table=info->open_tables ; table < info->end_table ; table++)
+ {
+ err=mi_rlast(table->table,NULL,inx);
+ info->last_used_table=table;
+
+ if (err == HA_ERR_END_OF_FILE)
+ continue;
+ if (err)
+ return err;
+
+ /* adding to queue */
+ queue_insert(&(info->by_key),(byte *)table);
+ }
+
+ if (!info->by_key.elements)
+ return HA_ERR_END_OF_FILE;
+
+ mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
+ return mi_rrnd(mi,buf,mi->lastpos);
+}
+
diff --git a/myisammrg/myrg_rnext.c b/myisammrg/myrg_rnext.c
new file mode 100644
index 00000000000..2bfa59be3ef
--- /dev/null
+++ b/myisammrg/myrg_rnext.c
@@ -0,0 +1,75 @@
+/* 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 "mymrgdef.h"
+
+ /*
+ Read next row with the same key as previous read
+ */
+
+int myrg_rnext(MYRG_INFO *info, byte *buf, int inx)
+{
+ MYRG_TABLE *table;
+ MI_INFO *mi;
+ uchar *key_buff;
+ uint pack_key_length;
+ int err;
+
+ /* at first, do rnext for the table found before */
+ err=mi_rnext(info->current_table->table,NULL,inx);
+ if (err == HA_ERR_END_OF_FILE)
+ {
+ queue_remove(&(info->by_key),0);
+ if (!info->by_key.elements)
+ return HA_ERR_END_OF_FILE;
+ }
+ else if (err)
+ return err;
+ else
+ {
+ /* Found here, adding to queue */
+ queue_top(&(info->by_key))=(byte *)(info->current_table);
+ queue_replaced(&(info->by_key));
+ }
+
+ /* next, let's finish myrg_rkey's initial scan */
+ table=info->last_used_table+1;
+ if (table < info->end_table)
+ {
+ mi=info->last_used_table->table;
+ key_buff=mi->lastkey+mi->s->base.max_key_length;
+ pack_key_length=mi->last_rkey_length;
+ for (; table < info->end_table ; table++)
+ {
+ mi=table->table;
+ err=_mi_rkey(mi,NULL,inx,key_buff,pack_key_length,HA_READ_KEY_OR_NEXT,FALSE);
+ info->last_used_table=table;
+
+ if (err == HA_ERR_KEY_NOT_FOUND)
+ continue;
+ if (err)
+ return err;
+
+ /* Found here, adding to queue */
+ queue_insert(&(info->by_key),(byte *)table);
+ }
+ }
+
+ /* now, mymerge's read_next is as simple as one queue_top */
+ mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
+ return mi_rrnd(mi,buf,mi->lastpos);
+}
+
diff --git a/myisammrg/myrg_rprev.c b/myisammrg/myrg_rprev.c
new file mode 100644
index 00000000000..3ee0894b42c
--- /dev/null
+++ b/myisammrg/myrg_rprev.c
@@ -0,0 +1,76 @@
+/* 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 "mymrgdef.h"
+
+ /*
+ Read previous row with the same key as previous read
+ */
+
+int myrg_rprev(MYRG_INFO *info, byte *buf, int inx)
+{
+ MYRG_TABLE *table;
+ MI_INFO *mi;
+ uchar *key_buff;
+ uint pack_key_length;
+ int err;
+
+ /* at first, do rnext for the table found before */
+ err=mi_rprev(info->current_table->table,NULL,inx);
+ if (err == HA_ERR_END_OF_FILE)
+ {
+ queue_remove(&(info->by_key),0);
+ if (!info->by_key.elements)
+ return HA_ERR_END_OF_FILE;
+ }
+ else if (err)
+ return err;
+ else
+ {
+ /* Found here, adding to queue */
+ queue_top(&(info->by_key))=(byte *)(info->current_table);
+ queue_replaced(&(info->by_key));
+ }
+
+ /* next, let's finish myrg_rkey's initial scan */
+ table=info->last_used_table+1;
+ if (table < info->end_table)
+ {
+ mi=info->last_used_table->table;
+ key_buff=mi->lastkey+mi->s->base.max_key_length;
+ pack_key_length=mi->last_rkey_length;
+ for (; table < info->end_table ; table++)
+ {
+ mi=table->table;
+ err=_mi_rkey(mi,NULL,inx,key_buff,pack_key_length,HA_READ_KEY_OR_PREV,FALSE);
+ info->last_used_table=table;
+
+ if (err == HA_ERR_KEY_NOT_FOUND)
+ continue;
+ if (err)
+ return err;
+
+ /* Found here, adding to queue */
+ queue_insert(&(info->by_key),(byte *)table);
+ }
+ }
+
+ /* now, mymerge's read_prev is as simple as one queue_top */
+ mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
+ return mi_rrnd(mi,buf,mi->lastpos);
+}
+
+
diff --git a/myisammrg/myrg_rrnd.c b/myisammrg/myrg_rrnd.c
index 2e6b8faaa66..93c7282623d 100644
--- a/myisammrg/myrg_rrnd.c
+++ b/myisammrg/myrg_rrnd.c
@@ -81,7 +81,7 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos)
}
}
info->current_table=find_table(info->open_tables,
- info->last_used_table,filepos);
+ info->end_table-1,filepos);
isam_info=info->current_table->table;
isam_info->update&= HA_STATE_CHANGED;
return ((*isam_info->s->read_rnd)(isam_info,(byte*) buf,