~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/sp_test.c

Merging trunk changes from over weekend.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2002-2004 MySQL AB
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
16
 
/* Testing of the basic functions of a MyISAM spatial table        */
17
 
/* Written by Alex Barkov, who has a shared copyright to this code */
18
 
 
19
 
#include "myisam.h"
20
 
 
21
 
#ifdef HAVE_SPATIAL
22
 
#include "sp_defs.h"
23
 
 
24
 
#define MAX_REC_LENGTH 1024
25
 
#define KEYALG HA_KEY_ALG_RTREE
26
 
 
27
 
static void create_linestring(uchar *record,uint rownr);
28
 
static void print_record(uchar * record,my_off_t offs,const char * tail);
29
 
 
30
 
static void create_key(uchar *key,uint rownr);
31
 
static void print_key(const uchar *key,const char * tail);
32
 
 
33
 
static int run_test(const char *filename);
34
 
static int read_with_pos(MI_INFO * file, int silent);
35
 
 
36
 
static int rtree_CreateLineStringWKB(double *ords, uint n_dims, uint n_points,
37
 
                                     uchar *wkb);
38
 
static  void rtree_PrintWKB(uchar *wkb, uint n_dims);
39
 
 
40
 
static char blob_key[MAX_REC_LENGTH];
41
 
 
42
 
 
43
 
int main(int argc  __attribute__((unused)),char *argv[])
44
 
{
45
 
  MY_INIT(argv[0]);
46
 
  exit(run_test("sp_test"));
47
 
}
48
 
 
49
 
 
50
 
int run_test(const char *filename)
51
 
{
52
 
  MI_INFO        *file;
53
 
  MI_UNIQUEDEF   uniquedef;
54
 
  MI_CREATE_INFO create_info;
55
 
  MI_COLUMNDEF   recinfo[20];
56
 
  MI_KEYDEF      keyinfo[20];
57
 
  HA_KEYSEG      keyseg[20];
58
 
  key_range      min_range, max_range;
59
 
  int silent=0;
60
 
  int create_flag=0;
61
 
  int null_fields=0;
62
 
  int nrecords=30;
63
 
  int uniques=0;
64
 
  int i;
65
 
  int error;
66
 
  int row_count=0;
67
 
  uchar record[MAX_REC_LENGTH];
68
 
  uchar key[MAX_REC_LENGTH];
69
 
  uchar read_record[MAX_REC_LENGTH];
70
 
  int upd=10;
71
 
  ha_rows hrows;
72
 
  
73
 
  /* Define a column for NULLs and DEL markers*/
74
 
  
75
 
  recinfo[0].type=FIELD_NORMAL;
76
 
  recinfo[0].length=1; /* For NULL bits */
77
 
  
78
 
  
79
 
  /* Define spatial column  */
80
 
  
81
 
  recinfo[1].type=FIELD_BLOB;
82
 
  recinfo[1].length=4 + portable_sizeof_char_ptr;
83
 
  
84
 
  
85
 
  
86
 
  /* Define a key with 1 spatial segment */
87
 
  
88
 
  keyinfo[0].seg=keyseg;
89
 
  keyinfo[0].keysegs=1;
90
 
  keyinfo[0].flag=HA_SPATIAL;
91
 
  keyinfo[0].key_alg=KEYALG;
92
 
  
93
 
  keyinfo[0].seg[0].type= HA_KEYTYPE_BINARY;
94
 
  keyinfo[0].seg[0].flag=0;
95
 
  keyinfo[0].seg[0].start= 1;
96
 
  keyinfo[0].seg[0].length=1; /* Spatial ignores it anyway */
97
 
  keyinfo[0].seg[0].null_bit= null_fields ? 2 : 0;
98
 
  keyinfo[0].seg[0].null_pos=0;
99
 
  keyinfo[0].seg[0].language=default_charset_info->number;
100
 
  keyinfo[0].seg[0].bit_start=4; /* Long BLOB */
101
 
  
102
 
  
103
 
  if (!silent)
104
 
    printf("- Creating isam-file\n");
105
 
  
106
 
  bzero((char*) &create_info,sizeof(create_info));
107
 
  create_info.max_rows=10000000;
108
 
  
109
 
  if (mi_create(filename,
110
 
                1,            /*  keys   */
111
 
                keyinfo,
112
 
                2, /* columns */
113
 
                recinfo,uniques,&uniquedef,&create_info,create_flag))
114
 
    goto err;
115
 
  
116
 
  if (!silent)
117
 
    printf("- Open isam-file\n");
118
 
  
119
 
  if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
120
 
    goto err;
121
 
  
122
 
  if (!silent)
123
 
    printf("- Writing key:s\n");
124
 
  
125
 
  for (i=0; i<nrecords; i++ )
126
 
  {
127
 
    create_linestring(record,i);
128
 
    error=mi_write(file,record);
129
 
    print_record(record,mi_position(file),"\n");
130
 
    if (!error)
131
 
    {
132
 
      row_count++;
133
 
    }
134
 
    else
135
 
    {
136
 
      printf("mi_write: %d\n", error);
137
 
      goto err;
138
 
    }
139
 
  }
140
 
 
141
 
  if ((error=read_with_pos(file,silent)))
142
 
    goto err;
143
 
 
144
 
  if (!silent)
145
 
    printf("- Deleting rows with position\n");
146
 
  for (i=0; i < nrecords/4; i++)
147
 
  {
148
 
    my_errno=0;
149
 
    bzero((char*) read_record,MAX_REC_LENGTH);
150
 
    error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
151
 
    if (error)
152
 
    {
153
 
      printf("pos: %2d  mi_rrnd: %3d  errno: %3d\n",i,error,my_errno);
154
 
      goto err;
155
 
    }
156
 
    print_record(read_record,mi_position(file),"\n");
157
 
    error=mi_delete(file,read_record);
158
 
    if (error)
159
 
    {
160
 
      printf("pos: %2d mi_delete: %3d errno: %3d\n",i,error,my_errno);
161
 
      goto err;
162
 
    }
163
 
  }
164
 
 
165
 
  if (!silent)
166
 
    printf("- Updating rows with position\n");
167
 
  for (i=0; i < nrecords/2 ; i++)
168
 
  {
169
 
    my_errno=0;
170
 
    bzero((char*) read_record,MAX_REC_LENGTH);
171
 
    error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
172
 
    if (error)
173
 
    {
174
 
      if (error==HA_ERR_RECORD_DELETED)
175
 
        continue;
176
 
      printf("pos: %2d  mi_rrnd: %3d  errno: %3d\n",i,error,my_errno);
177
 
      goto err;
178
 
    }
179
 
    print_record(read_record,mi_position(file),"");
180
 
    create_linestring(record,i+nrecords*upd);
181
 
    printf("\t-> ");
182
 
    print_record(record,mi_position(file),"\n");
183
 
    error=mi_update(file,read_record,record);
184
 
    if (error)
185
 
    {
186
 
      printf("pos: %2d  mi_update: %3d  errno: %3d\n",i,error,my_errno);
187
 
      goto err;
188
 
    }
189
 
  }
190
 
 
191
 
  if ((error=read_with_pos(file,silent)))
192
 
    goto err;
193
 
 
194
 
  if (!silent)
195
 
    printf("- Test mi_rkey then a sequence of mi_rnext_same\n");
196
 
  
197
 
  create_key(key, nrecords*4/5);
198
 
  print_key(key,"  search for INTERSECT\n");
199
 
  
200
 
  if ((error=mi_rkey(file,read_record,0,key,0,HA_READ_MBR_INTERSECT)))
201
 
  {
202
 
    printf("mi_rkey: %3d  errno: %3d\n",error,my_errno);
203
 
    goto err;
204
 
  }
205
 
  print_record(read_record,mi_position(file),"  mi_rkey\n");
206
 
  row_count=1;
207
 
 
208
 
  for (;;)
209
 
  {
210
 
    if ((error=mi_rnext_same(file,read_record)))
211
 
    {
212
 
      if (error==HA_ERR_END_OF_FILE)
213
 
        break;
214
 
      printf("mi_next: %3d  errno: %3d\n",error,my_errno);
215
 
      goto err;
216
 
    }
217
 
    print_record(read_record,mi_position(file),"  mi_rnext_same\n");
218
 
      row_count++;
219
 
  }
220
 
  printf("     %d rows\n",row_count);
221
 
 
222
 
  if (!silent)
223
 
    printf("- Test mi_rfirst then a sequence of mi_rnext\n");
224
 
 
225
 
  error=mi_rfirst(file,read_record,0);
226
 
  if (error)
227
 
  {
228
 
    printf("mi_rfirst: %3d  errno: %3d\n",error,my_errno);
229
 
    goto err;
230
 
  }
231
 
  row_count=1;
232
 
  print_record(read_record,mi_position(file),"  mi_frirst\n");
233
 
  
234
 
  for(i=0;i<nrecords;i++) {
235
 
    if ((error=mi_rnext(file,read_record,0)))
236
 
    {
237
 
      if (error==HA_ERR_END_OF_FILE)
238
 
        break;
239
 
      printf("mi_next: %3d  errno: %3d\n",error,my_errno);
240
 
      goto err;
241
 
    }
242
 
    print_record(read_record,mi_position(file),"  mi_rnext\n");
243
 
    row_count++;
244
 
  }
245
 
  printf("     %d rows\n",row_count);
246
 
 
247
 
  if (!silent)
248
 
    printf("- Test mi_records_in_range()\n");
249
 
 
250
 
  create_key(key, nrecords*upd);
251
 
  print_key(key," INTERSECT\n");
252
 
  min_range.key= key;
253
 
  min_range.length= 1000;                       /* Big enough */
254
 
  min_range.flag= HA_READ_MBR_INTERSECT;
255
 
  max_range.key= record+1;
256
 
  max_range.length= 1000;                       /* Big enough */
257
 
  max_range.flag= HA_READ_KEY_EXACT;
258
 
  hrows= mi_records_in_range(file, 0, &min_range, &max_range);
259
 
  printf("     %ld rows\n", (long) hrows);
260
 
 
261
 
  if (mi_close(file)) goto err;
262
 
  my_end(MY_CHECK_ERROR);
263
 
  return 0;
264
 
  
265
 
err:
266
 
  printf("got error: %3d when using myisam-database\n",my_errno);
267
 
  return 1;           /* skip warning */
268
 
}
269
 
 
270
 
 
271
 
static int read_with_pos (MI_INFO * file,int silent)
272
 
{
273
 
  int error;
274
 
  int i;
275
 
  uchar read_record[MAX_REC_LENGTH];
276
 
  int rows=0;
277
 
 
278
 
  if (!silent)
279
 
    printf("- Reading rows with position\n");
280
 
  for (i=0;;i++)
281
 
  {
282
 
    my_errno=0;
283
 
    bzero((char*) read_record,MAX_REC_LENGTH);
284
 
    error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
285
 
    if (error)
286
 
    {
287
 
      if (error==HA_ERR_END_OF_FILE)
288
 
        break;
289
 
      if (error==HA_ERR_RECORD_DELETED)
290
 
        continue;
291
 
      printf("pos: %2d  mi_rrnd: %3d  errno: %3d\n",i,error,my_errno);
292
 
      return error;
293
 
    }
294
 
    rows++;
295
 
    print_record(read_record,mi_position(file),"\n");
296
 
  }
297
 
  printf("     %d rows\n",rows);
298
 
  return 0;
299
 
}
300
 
 
301
 
 
302
 
#ifdef NOT_USED
303
 
static void bprint_record(uchar * record,
304
 
                          my_off_t offs __attribute__((unused)),
305
 
                          const char * tail)
306
 
{
307
 
  int i;
308
 
  char * pos;
309
 
  i=(unsigned char)record[0];
310
 
  printf("%02X ",i);
311
 
  
312
 
  for( pos=record+1, i=0; i<32; i++,pos++)
313
 
  {
314
 
    int b=(unsigned char)*pos;
315
 
    printf("%02X",b);
316
 
  }
317
 
  printf("%s",tail);
318
 
}
319
 
#endif
320
 
 
321
 
 
322
 
static void print_record(uchar * record, my_off_t offs,const char * tail)
323
 
{
324
 
  uchar *pos;
325
 
  char *ptr;
326
 
  uint len;
327
 
  
328
 
  printf("     rec=(%d)",(unsigned char)record[0]);
329
 
  pos=record+1;
330
 
  len=sint4korr(pos);
331
 
  pos+=4;
332
 
  printf(" len=%d ",len);
333
 
  memcpy_fixed(&ptr,pos,sizeof(char*));
334
 
  if (ptr)
335
 
    rtree_PrintWKB((uchar*) ptr,SPDIMS);
336
 
  else
337
 
    printf("<NULL> ");
338
 
  printf(" offs=%ld ",(long int)offs);
339
 
  printf("%s",tail);
340
 
}
341
 
 
342
 
 
343
 
#ifdef NOT_USED
344
 
static void create_point(uchar *record,uint rownr)
345
 
{
346
 
   uint tmp;
347
 
   char *ptr;
348
 
   char *pos=record;
349
 
   double x[200];
350
 
   int i;
351
 
   
352
 
   for(i=0;i<SPDIMS;i++)
353
 
     x[i]=rownr;
354
 
   
355
 
   bzero((char*) record,MAX_REC_LENGTH);
356
 
   *pos=0x01; /* DEL marker */
357
 
   pos++;
358
 
   
359
 
   memset(blob_key,0,sizeof(blob_key));
360
 
   tmp=rtree_CreatePointWKB(x,SPDIMS,blob_key);
361
 
   
362
 
   int4store(pos,tmp);
363
 
   pos+=4;
364
 
   
365
 
   ptr=blob_key;
366
 
   memcpy_fixed(pos,&ptr,sizeof(char*));
367
 
}
368
 
#endif
369
 
 
370
 
 
371
 
static void create_linestring(uchar *record,uint rownr)
372
 
{
373
 
   uint tmp;
374
 
   char *ptr;
375
 
   uchar *pos= record;
376
 
   double x[200];
377
 
   int i,j;
378
 
   int npoints=2;
379
 
   
380
 
   for(j=0;j<npoints;j++)
381
 
     for(i=0;i<SPDIMS;i++)
382
 
       x[i+j*SPDIMS]=rownr*j;
383
 
   
384
 
   bzero((char*) record,MAX_REC_LENGTH);
385
 
   *pos=0x01; /* DEL marker */
386
 
   pos++;
387
 
   
388
 
   memset(blob_key,0,sizeof(blob_key));
389
 
   tmp=rtree_CreateLineStringWKB(x,SPDIMS,npoints, (uchar*) blob_key);
390
 
   
391
 
   int4store(pos,tmp);
392
 
   pos+=4;
393
 
   
394
 
   ptr=blob_key;
395
 
   memcpy_fixed(pos,&ptr,sizeof(char*));
396
 
}
397
 
 
398
 
 
399
 
static void create_key(uchar *key,uint rownr)
400
 
{
401
 
   double c=rownr;
402
 
   uchar *pos;
403
 
   uint i;
404
 
   
405
 
   bzero(key,MAX_REC_LENGTH);
406
 
   for (pos=key, i=0; i<2*SPDIMS; i++)
407
 
   {
408
 
     float8store(pos,c);
409
 
     pos+=sizeof(c);
410
 
   }
411
 
}
412
 
 
413
 
static void print_key(const uchar *key,const char * tail)
414
 
{
415
 
  double c;
416
 
  uint i;
417
 
  
418
 
  printf("     key=");
419
 
  for (i=0; i<2*SPDIMS; i++)
420
 
  {
421
 
    float8get(c,key);
422
 
    key+=sizeof(c);
423
 
    printf("%.14g ",c);
424
 
  }
425
 
  printf("%s",tail);
426
 
}
427
 
 
428
 
 
429
 
#ifdef NOT_USED
430
 
 
431
 
static int rtree_CreatePointWKB(double *ords, uint n_dims, uchar *wkb)
432
 
{
433
 
  uint i;
434
 
 
435
 
  *wkb = wkbXDR;
436
 
  ++wkb;
437
 
  int4store(wkb, wkbPoint);
438
 
  wkb += 4;
439
 
 
440
 
  for (i=0; i < n_dims; ++i)
441
 
  {
442
 
    float8store(wkb, ords[i]);
443
 
    wkb += 8;
444
 
  }
445
 
  return 5 + n_dims * 8;
446
 
}
447
 
#endif
448
 
 
449
 
 
450
 
static int rtree_CreateLineStringWKB(double *ords, uint n_dims, uint n_points,
451
 
                                     uchar *wkb)
452
 
{
453
 
  uint i;
454
 
  uint n_ords = n_dims * n_points;
455
 
 
456
 
  *wkb = wkbXDR;
457
 
  ++wkb;
458
 
  int4store(wkb, wkbLineString);
459
 
  wkb += 4;
460
 
  int4store(wkb, n_points);
461
 
  wkb += 4;
462
 
  for (i=0; i < n_ords; ++i)
463
 
  {
464
 
    float8store(wkb, ords[i]);
465
 
    wkb += 8;
466
 
  }
467
 
  return 9 + n_points * n_dims * 8;
468
 
}
469
 
 
470
 
 
471
 
static void rtree_PrintWKB(uchar *wkb, uint n_dims)
472
 
{
473
 
  uint wkb_type;
474
 
 
475
 
  ++wkb;
476
 
  wkb_type = uint4korr(wkb);
477
 
  wkb += 4;
478
 
 
479
 
  switch ((enum wkbType)wkb_type)
480
 
  {
481
 
    case wkbPoint:
482
 
    {
483
 
      uint i;
484
 
      double ord;
485
 
 
486
 
      printf("POINT(");
487
 
      for (i=0; i < n_dims; ++i)
488
 
      {
489
 
        float8get(ord, wkb);
490
 
        wkb += 8;
491
 
        printf("%.14g", ord);
492
 
        if (i < n_dims - 1)
493
 
          printf(" ");
494
 
        else
495
 
          printf(")");
496
 
      }
497
 
      break;
498
 
    }
499
 
    case wkbLineString:
500
 
    {
501
 
      uint p, i;
502
 
      uint n_points;
503
 
      double ord;
504
 
 
505
 
      printf("LineString(");
506
 
      n_points = uint4korr(wkb);
507
 
      wkb += 4;
508
 
      for (p=0; p < n_points; ++p)
509
 
      {
510
 
        for (i=0; i < n_dims; ++i)
511
 
        {
512
 
          float8get(ord, wkb);
513
 
          wkb += 8;
514
 
          printf("%.14g", ord);
515
 
          if (i < n_dims - 1)
516
 
            printf(" ");
517
 
        }
518
 
        if (p < n_points - 1)
519
 
          printf(", ");
520
 
        else
521
 
          printf(")");
522
 
      }
523
 
      break;
524
 
    }
525
 
    case wkbPolygon:
526
 
    {
527
 
      printf("POLYGON(...)");
528
 
      break;
529
 
    }
530
 
    case wkbMultiPoint:
531
 
    {
532
 
      printf("MULTIPOINT(...)");
533
 
      break;
534
 
    }
535
 
    case wkbMultiLineString:
536
 
    {
537
 
      printf("MULTILINESTRING(...)");
538
 
      break;
539
 
    }
540
 
    case wkbMultiPolygon:
541
 
    {
542
 
      printf("MULTIPOLYGON(...)");
543
 
      break;
544
 
    }
545
 
    case wkbGeometryCollection:
546
 
    {
547
 
      printf("GEOMETRYCOLLECTION(...)");
548
 
      break;
549
 
    }
550
 
    default:
551
 
    {
552
 
      printf("UNKNOWN GEOMETRY TYPE");
553
 
      break;
554
 
    }
555
 
  }
556
 
}
557
 
 
558
 
#else
559
 
int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
560
 
{
561
 
  exit(0);
562
 
}
563
 
#endif /*HAVE_SPATIAL*/
564
 
 
565
 
#include "mi_extrafunc.h"