1
/* Copyright (C) 2002-2004 MySQL AB
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.
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.
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 */
16
/* Testing of the basic functions of a MyISAM spatial table */
17
/* Written by Alex Barkov, who has a shared copyright to this code */
24
#define MAX_REC_LENGTH 1024
25
#define KEYALG HA_KEY_ALG_RTREE
27
static void create_linestring(uchar *record,uint rownr);
28
static void print_record(uchar * record,my_off_t offs,const char * tail);
30
static void create_key(uchar *key,uint rownr);
31
static void print_key(const uchar *key,const char * tail);
33
static int run_test(const char *filename);
34
static int read_with_pos(MI_INFO * file, int silent);
36
static int rtree_CreateLineStringWKB(double *ords, uint n_dims, uint n_points,
38
static void rtree_PrintWKB(uchar *wkb, uint n_dims);
40
static char blob_key[MAX_REC_LENGTH];
43
int main(int argc __attribute__((unused)),char *argv[])
46
exit(run_test("sp_test"));
50
int run_test(const char *filename)
53
MI_UNIQUEDEF uniquedef;
54
MI_CREATE_INFO create_info;
55
MI_COLUMNDEF recinfo[20];
56
MI_KEYDEF keyinfo[20];
58
key_range min_range, max_range;
67
uchar record[MAX_REC_LENGTH];
68
uchar key[MAX_REC_LENGTH];
69
uchar read_record[MAX_REC_LENGTH];
73
/* Define a column for NULLs and DEL markers*/
75
recinfo[0].type=FIELD_NORMAL;
76
recinfo[0].length=1; /* For NULL bits */
79
/* Define spatial column */
81
recinfo[1].type=FIELD_BLOB;
82
recinfo[1].length=4 + portable_sizeof_char_ptr;
86
/* Define a key with 1 spatial segment */
88
keyinfo[0].seg=keyseg;
90
keyinfo[0].flag=HA_SPATIAL;
91
keyinfo[0].key_alg=KEYALG;
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 */
104
printf("- Creating isam-file\n");
106
bzero((char*) &create_info,sizeof(create_info));
107
create_info.max_rows=10000000;
109
if (mi_create(filename,
113
recinfo,uniques,&uniquedef,&create_info,create_flag))
117
printf("- Open isam-file\n");
119
if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
123
printf("- Writing key:s\n");
125
for (i=0; i<nrecords; i++ )
127
create_linestring(record,i);
128
error=mi_write(file,record);
129
print_record(record,mi_position(file),"\n");
136
printf("mi_write: %d\n", error);
141
if ((error=read_with_pos(file,silent)))
145
printf("- Deleting rows with position\n");
146
for (i=0; i < nrecords/4; i++)
149
bzero((char*) read_record,MAX_REC_LENGTH);
150
error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
153
printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno);
156
print_record(read_record,mi_position(file),"\n");
157
error=mi_delete(file,read_record);
160
printf("pos: %2d mi_delete: %3d errno: %3d\n",i,error,my_errno);
166
printf("- Updating rows with position\n");
167
for (i=0; i < nrecords/2 ; i++)
170
bzero((char*) read_record,MAX_REC_LENGTH);
171
error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
174
if (error==HA_ERR_RECORD_DELETED)
176
printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno);
179
print_record(read_record,mi_position(file),"");
180
create_linestring(record,i+nrecords*upd);
182
print_record(record,mi_position(file),"\n");
183
error=mi_update(file,read_record,record);
186
printf("pos: %2d mi_update: %3d errno: %3d\n",i,error,my_errno);
191
if ((error=read_with_pos(file,silent)))
195
printf("- Test mi_rkey then a sequence of mi_rnext_same\n");
197
create_key(key, nrecords*4/5);
198
print_key(key," search for INTERSECT\n");
200
if ((error=mi_rkey(file,read_record,0,key,0,HA_READ_MBR_INTERSECT)))
202
printf("mi_rkey: %3d errno: %3d\n",error,my_errno);
205
print_record(read_record,mi_position(file)," mi_rkey\n");
210
if ((error=mi_rnext_same(file,read_record)))
212
if (error==HA_ERR_END_OF_FILE)
214
printf("mi_next: %3d errno: %3d\n",error,my_errno);
217
print_record(read_record,mi_position(file)," mi_rnext_same\n");
220
printf(" %d rows\n",row_count);
223
printf("- Test mi_rfirst then a sequence of mi_rnext\n");
225
error=mi_rfirst(file,read_record,0);
228
printf("mi_rfirst: %3d errno: %3d\n",error,my_errno);
232
print_record(read_record,mi_position(file)," mi_frirst\n");
234
for(i=0;i<nrecords;i++) {
235
if ((error=mi_rnext(file,read_record,0)))
237
if (error==HA_ERR_END_OF_FILE)
239
printf("mi_next: %3d errno: %3d\n",error,my_errno);
242
print_record(read_record,mi_position(file)," mi_rnext\n");
245
printf(" %d rows\n",row_count);
248
printf("- Test mi_records_in_range()\n");
250
create_key(key, nrecords*upd);
251
print_key(key," INTERSECT\n");
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);
261
if (mi_close(file)) goto err;
262
my_end(MY_CHECK_ERROR);
266
printf("got error: %3d when using myisam-database\n",my_errno);
267
return 1; /* skip warning */
271
static int read_with_pos (MI_INFO * file,int silent)
275
uchar read_record[MAX_REC_LENGTH];
279
printf("- Reading rows with position\n");
283
bzero((char*) read_record,MAX_REC_LENGTH);
284
error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
287
if (error==HA_ERR_END_OF_FILE)
289
if (error==HA_ERR_RECORD_DELETED)
291
printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno);
295
print_record(read_record,mi_position(file),"\n");
297
printf(" %d rows\n",rows);
303
static void bprint_record(uchar * record,
304
my_off_t offs __attribute__((unused)),
309
i=(unsigned char)record[0];
312
for( pos=record+1, i=0; i<32; i++,pos++)
314
int b=(unsigned char)*pos;
322
static void print_record(uchar * record, my_off_t offs,const char * tail)
328
printf(" rec=(%d)",(unsigned char)record[0]);
332
printf(" len=%d ",len);
333
memcpy_fixed(&ptr,pos,sizeof(char*));
335
rtree_PrintWKB((uchar*) ptr,SPDIMS);
338
printf(" offs=%ld ",(long int)offs);
344
static void create_point(uchar *record,uint rownr)
352
for(i=0;i<SPDIMS;i++)
355
bzero((char*) record,MAX_REC_LENGTH);
356
*pos=0x01; /* DEL marker */
359
memset(blob_key,0,sizeof(blob_key));
360
tmp=rtree_CreatePointWKB(x,SPDIMS,blob_key);
366
memcpy_fixed(pos,&ptr,sizeof(char*));
371
static void create_linestring(uchar *record,uint rownr)
380
for(j=0;j<npoints;j++)
381
for(i=0;i<SPDIMS;i++)
382
x[i+j*SPDIMS]=rownr*j;
384
bzero((char*) record,MAX_REC_LENGTH);
385
*pos=0x01; /* DEL marker */
388
memset(blob_key,0,sizeof(blob_key));
389
tmp=rtree_CreateLineStringWKB(x,SPDIMS,npoints, (uchar*) blob_key);
395
memcpy_fixed(pos,&ptr,sizeof(char*));
399
static void create_key(uchar *key,uint rownr)
405
bzero(key,MAX_REC_LENGTH);
406
for (pos=key, i=0; i<2*SPDIMS; i++)
413
static void print_key(const uchar *key,const char * tail)
419
for (i=0; i<2*SPDIMS; i++)
431
static int rtree_CreatePointWKB(double *ords, uint n_dims, uchar *wkb)
437
int4store(wkb, wkbPoint);
440
for (i=0; i < n_dims; ++i)
442
float8store(wkb, ords[i]);
445
return 5 + n_dims * 8;
450
static int rtree_CreateLineStringWKB(double *ords, uint n_dims, uint n_points,
454
uint n_ords = n_dims * n_points;
458
int4store(wkb, wkbLineString);
460
int4store(wkb, n_points);
462
for (i=0; i < n_ords; ++i)
464
float8store(wkb, ords[i]);
467
return 9 + n_points * n_dims * 8;
471
static void rtree_PrintWKB(uchar *wkb, uint n_dims)
476
wkb_type = uint4korr(wkb);
479
switch ((enum wkbType)wkb_type)
487
for (i=0; i < n_dims; ++i)
491
printf("%.14g", ord);
505
printf("LineString(");
506
n_points = uint4korr(wkb);
508
for (p=0; p < n_points; ++p)
510
for (i=0; i < n_dims; ++i)
514
printf("%.14g", ord);
518
if (p < n_points - 1)
527
printf("POLYGON(...)");
532
printf("MULTIPOINT(...)");
535
case wkbMultiLineString:
537
printf("MULTILINESTRING(...)");
540
case wkbMultiPolygon:
542
printf("MULTIPOLYGON(...)");
545
case wkbGeometryCollection:
547
printf("GEOMETRYCOLLECTION(...)");
552
printf("UNKNOWN GEOMETRY TYPE");
559
int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
563
#endif /*HAVE_SPATIAL*/
565
#include "mi_extrafunc.h"