sp_test.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:12k
源码类别:

MySQL数据库

开发平台:

Visual C++

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