MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rt_test.c
1 /* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 /* Testing of the basic functions of a MyISAM rtree table */
17 /* Written by Alex Barkov who has a shared copyright to this code */
18 
19 
20 #include "myisam.h"
21 
22 #ifdef HAVE_RTREE_KEYS
23 
24 #include "rt_index.h"
25 
26 #define MAX_REC_LENGTH 1024
27 #define ndims 2
28 #define KEYALG HA_KEY_ALG_RTREE
29 
30 static int read_with_pos(MI_INFO * file, int silent);
31 static void create_record(uchar *record,uint rownr);
32 static void create_record1(uchar *record,uint rownr);
33 static void print_record(uchar * record,my_off_t offs,const char * tail);
34 static int run_test(const char *filename);
35 
36 static double rt_data[]=
37 {
38  /*1*/ 0,10,0,10,
39  /*2*/ 5,15,0,10,
40  /*3*/ 0,10,5,15,
41  /*4*/ 10,20,10,20,
42  /*5*/ 0,10,0,10,
43  /*6*/ 5,15,0,10,
44  /*7*/ 0,10,5,15,
45  /*8*/ 10,20,10,20,
46  /*9*/ 0,10,0,10,
47  /*10*/ 5,15,0,10,
48  /*11*/ 0,10,5,15,
49  /*12*/ 10,20,10,20,
50  /*13*/ 0,10,0,10,
51  /*14*/ 5,15,0,10,
52  /*15*/ 0,10,5,15,
53  /*16*/ 10,20,10,20,
54  /*17*/ 5,15,0,10,
55  /*18*/ 0,10,5,15,
56  /*19*/ 10,20,10,20,
57  /*20*/ 0,10,0,10,
58 
59  /*1*/ 100,110,0,10,
60  /*2*/ 105,115,0,10,
61  /*3*/ 100,110,5,15,
62  /*4*/ 110,120,10,20,
63  /*5*/ 100,110,0,10,
64  /*6*/ 105,115,0,10,
65  /*7*/ 100,110,5,15,
66  /*8*/ 110,120,10,20,
67  /*9*/ 100,110,0,10,
68  /*10*/ 105,115,0,10,
69  /*11*/ 100,110,5,15,
70  /*12*/ 110,120,10,20,
71  /*13*/ 100,110,0,10,
72  /*14*/ 105,115,0,10,
73  /*15*/ 100,110,5,15,
74  /*16*/ 110,120,10,20,
75  /*17*/ 105,115,0,10,
76  /*18*/ 100,110,5,15,
77  /*19*/ 110,120,10,20,
78  /*20*/ 100,110,0,10,
79  -1
80 };
81 
82 int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
83 {
84  MY_INIT(argv[0]);
85  exit(run_test("rt_test"));
86 }
87 
88 
89 static int run_test(const char *filename)
90 {
91  MI_INFO *file;
92  MI_UNIQUEDEF uniquedef;
93  MI_CREATE_INFO create_info;
94  MI_COLUMNDEF recinfo[20];
95  MI_KEYDEF keyinfo[20];
96  HA_KEYSEG keyseg[20];
97  key_range range;
98 
99  int silent=0;
100  int opt_unique=0;
101  int create_flag=0;
102  int key_type=HA_KEYTYPE_DOUBLE;
103  int key_length=8;
104  int null_fields=0;
105  int nrecords=sizeof(rt_data)/(sizeof(double)*4);/* 3000;*/
106  int rec_length=0;
107  int uniques=0;
108  int i;
109  int error;
110  int row_count=0;
111  uchar record[MAX_REC_LENGTH];
112  uchar read_record[MAX_REC_LENGTH];
113  int upd= 10;
114  ha_rows hrows;
115 
116  /* Define a column for NULLs and DEL markers*/
117 
118  recinfo[0].type=FIELD_NORMAL;
119  recinfo[0].length=1; /* For NULL bits */
120  rec_length=1;
121 
122  /* Define 2*ndims columns for coordinates*/
123 
124  for (i=1; i<=2*ndims ;i++){
125  recinfo[i].type=FIELD_NORMAL;
126  recinfo[i].length=key_length;
127  rec_length+=key_length;
128  }
129 
130  /* Define a key with 2*ndims segments */
131 
132  keyinfo[0].seg=keyseg;
133  keyinfo[0].keysegs=2*ndims;
134  keyinfo[0].flag=0;
135  keyinfo[0].key_alg=KEYALG;
136 
137  for (i=0; i<2*ndims; i++){
138  keyinfo[0].seg[i].type= key_type;
139  keyinfo[0].seg[i].flag=0; /* Things like HA_REVERSE_SORT */
140  keyinfo[0].seg[i].start= (key_length*i)+1;
141  keyinfo[0].seg[i].length=key_length;
142  keyinfo[0].seg[i].null_bit= null_fields ? 2 : 0;
143  keyinfo[0].seg[i].null_pos=0;
144  keyinfo[0].seg[i].language=default_charset_info->number;
145  }
146 
147  if (!silent)
148  printf("- Creating isam-file\n");
149 
150  memset(&create_info, 0, sizeof(create_info));
151  create_info.max_rows=10000000;
152 
153  if (mi_create(filename,
154  1, /* keys */
155  keyinfo,
156  1+2*ndims+opt_unique, /* columns */
157  recinfo,uniques,&uniquedef,&create_info,create_flag))
158  goto err;
159 
160  if (!silent)
161  printf("- Open isam-file\n");
162 
163  if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
164  goto err;
165 
166  if (!silent)
167  printf("- Writing key:s\n");
168 
169  for (i=0; i<nrecords; i++ )
170  {
171  create_record(record,i);
172  error=mi_write(file,record);
173  print_record(record,mi_position(file),"\n");
174  if (!error)
175  {
176  row_count++;
177  }
178  else
179  {
180  printf("mi_write: %d\n", error);
181  goto err;
182  }
183  }
184 
185  if ((error=read_with_pos(file,silent)))
186  goto err;
187 
188  if (!silent)
189  printf("- Reading rows with key\n");
190 
191  for (i=0 ; i < nrecords ; i++)
192  {
193  my_errno=0;
194  create_record(record,i);
195 
196  memset(read_record, 0, MAX_REC_LENGTH);
197  error=mi_rkey(file,read_record,0,record+1,0,HA_READ_MBR_EQUAL);
198 
199  if (error && error!=HA_ERR_KEY_NOT_FOUND)
200  {
201  printf(" mi_rkey: %3d errno: %3d\n",error,my_errno);
202  goto err;
203  }
204  if (error == HA_ERR_KEY_NOT_FOUND)
205  {
206  print_record(record,mi_position(file)," NOT FOUND\n");
207  continue;
208  }
209  print_record(read_record,mi_position(file),"\n");
210  }
211 
212  if (!silent)
213  printf("- Deleting rows\n");
214  for (i=0; i < nrecords/4; i++)
215  {
216  my_errno=0;
217  memset(read_record, 0, MAX_REC_LENGTH);
218  error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
219  if (error)
220  {
221  printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno);
222  goto err;
223  }
224  print_record(read_record,mi_position(file),"\n");
225 
226  error=mi_delete(file,read_record);
227  if (error)
228  {
229  printf("pos: %2d mi_delete: %3d errno: %3d\n",i,error,my_errno);
230  goto err;
231  }
232  }
233 
234  if (!silent)
235  printf("- Updating rows with position\n");
236  for (i=0; i < (nrecords - nrecords/4) ; i++)
237  {
238  my_errno=0;
239  memset(read_record, 0, MAX_REC_LENGTH);
240  error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
241  if (error)
242  {
243  if (error==HA_ERR_RECORD_DELETED)
244  continue;
245  printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno);
246  goto err;
247  }
248  print_record(read_record,mi_position(file),"");
249  create_record(record,i+nrecords*upd);
250  printf("\t-> ");
251  print_record(record,mi_position(file),"\n");
252  error=mi_update(file,read_record,record);
253  if (error)
254  {
255  printf("pos: %2d mi_update: %3d errno: %3d\n",i,error,my_errno);
256  goto err;
257  }
258  }
259 
260  if ((error=read_with_pos(file,silent)))
261  goto err;
262 
263  if (!silent)
264  printf("- Test mi_rkey then a sequence of mi_rnext_same\n");
265 
266  create_record(record, nrecords*4/5);
267  print_record(record,0," search for\n");
268 
269  if ((error=mi_rkey(file,read_record,0,record+1,0,HA_READ_MBR_INTERSECT)))
270  {
271  printf("mi_rkey: %3d errno: %3d\n",error,my_errno);
272  goto err;
273  }
274  print_record(read_record,mi_position(file)," mi_rkey\n");
275  row_count=1;
276 
277  for (;;)
278  {
279  if ((error=mi_rnext_same(file,read_record)))
280  {
281  if (error==HA_ERR_END_OF_FILE)
282  break;
283  printf("mi_next: %3d errno: %3d\n",error,my_errno);
284  goto err;
285  }
286  print_record(read_record,mi_position(file)," mi_rnext_same\n");
287  row_count++;
288  }
289  printf(" %d rows\n",row_count);
290 
291  if (!silent)
292  printf("- Test mi_rfirst then a sequence of mi_rnext\n");
293 
294  error=mi_rfirst(file,read_record,0);
295  if (error)
296  {
297  printf("mi_rfirst: %3d errno: %3d\n",error,my_errno);
298  goto err;
299  }
300  row_count=1;
301  print_record(read_record,mi_position(file)," mi_frirst\n");
302 
303  for (i=0;i<nrecords;i++)
304  {
305  if ((error=mi_rnext(file,read_record,0)))
306  {
307  if (error==HA_ERR_END_OF_FILE)
308  break;
309  printf("mi_next: %3d errno: %3d\n",error,my_errno);
310  goto err;
311  }
312  print_record(read_record,mi_position(file)," mi_rnext\n");
313  row_count++;
314  }
315  printf(" %d rows\n",row_count);
316 
317  if (!silent)
318  printf("- Test mi_records_in_range()\n");
319 
320  create_record1(record, nrecords*4/5);
321  print_record(record,0,"\n");
322 
323  range.key= record+1;
324  range.length= 1000; /* Big enough */
325  range.flag= HA_READ_MBR_INTERSECT;
326  hrows= mi_records_in_range(file, 0, &range, (key_range*) 0);
327  printf(" %ld rows\n", (long) hrows);
328 
329  if (mi_close(file)) goto err;
330  my_end(MY_CHECK_ERROR);
331 
332  return 0;
333 
334 err:
335  printf("got error: %3d when using myisam-database\n",my_errno);
336  return 1; /* skip warning */
337 }
338 
339 
340 
341 static int read_with_pos (MI_INFO * file,int silent)
342 {
343  int error;
344  int i;
345  uchar read_record[MAX_REC_LENGTH];
346 
347  if (!silent)
348  printf("- Reading rows with position\n");
349  for (i=0;;i++)
350  {
351  my_errno=0;
352  memset(read_record, 0, MAX_REC_LENGTH);
353  error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
354  if (error)
355  {
356  if (error==HA_ERR_END_OF_FILE)
357  break;
358  if (error==HA_ERR_RECORD_DELETED)
359  continue;
360  printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno);
361  return error;
362  }
363  print_record(read_record,mi_position(file),"\n");
364  }
365  return 0;
366 }
367 
368 
369 static void print_record(uchar * record,
370  my_off_t offs __attribute__((unused)),
371  const char * tail)
372 {
373  int i;
374  uchar * pos;
375  double c;
376 
377  printf(" rec=(%d)",(unsigned char)record[0]);
378  for ( pos=record+1, i=0; i<2*ndims; i++)
379  {
380  memcpy(&c,pos,sizeof(c));
381  float8get(c,pos);
382  printf(" %.14g ",c);
383  pos+=sizeof(c);
384  }
385  printf("pos=%ld",(long int)offs);
386  printf("%s",tail);
387 }
388 
389 
390 
391 static void create_record1(uchar *record,uint rownr)
392 {
393  int i;
394  uchar * pos;
395  double c=rownr+10;
396 
397  memset(record, 0, MAX_REC_LENGTH);
398  record[0]=0x01; /* DEL marker */
399 
400  for (pos=record+1, i=0; i<2*ndims; i++)
401  {
402  memcpy(pos,&c,sizeof(c));
403  float8store(pos,c);
404  pos+=sizeof(c);
405  }
406 }
407 
408 
409 static void create_record(uchar *record,uint rownr)
410 {
411  int i;
412  uchar *pos;
413  double *data= rt_data+rownr*4;
414  record[0]=0x01; /* DEL marker */
415  for (pos=record+1, i=0; i<ndims*2; i++)
416  {
417  float8store(pos,data[i]);
418  pos+=8;
419  }
420 }
421 
422 #else
423 int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
424 {
425  exit(0);
426 }
427 #endif /*HAVE_RTREE_KEYS*/
428 
429 #include "mi_extrafunc.h"