LTP GCOV extension - code coverage report
Current view: directory - storage/maria - ma_sp_key.c
Test: maria-mtr.html
Date: 2009-03-04 Instrumented lines: 130
Code covered: 0.0 % Executed lines: 0

       1                 : /* Copyright (C) 2006 MySQL AB & Ramil Kalimullin
       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                 : #include "maria_def.h"
      17                 : #include "ma_blockrec.h"                        /* For ROW_FLAG_TRANSID */
      18                 : #include "trnman.h"
      19                 : 
      20                 : #ifdef HAVE_SPATIAL
      21                 : 
      22                 : #include "ma_sp_defs.h"
      23                 : 
      24                 : static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims,
      25                 :                              uchar byte_order, double *mbr);
      26                 : static int sp_get_point_mbr(uchar *(*wkb), uchar *end, uint n_dims,
      27                 :                            uchar byte_order, double *mbr);
      28                 : static int sp_get_linestring_mbr(uchar *(*wkb), uchar *end, uint n_dims,
      29                 :                                 uchar byte_order, double *mbr);
      30                 : static int sp_get_polygon_mbr(uchar *(*wkb), uchar *end, uint n_dims,
      31                 :                              uchar byte_order, double *mbr);
      32                 : static int sp_get_geometry_mbr(uchar *(*wkb), uchar *end, uint n_dims,
      33                 :                               double *mbr, int top);
      34                 : static int sp_mbr_from_wkb(uchar (*wkb), uint size, uint n_dims, double *mbr);
      35                 : 
      36                 : 
      37                 : /**
      38                 :    Create spactial key
      39                 : */
      40                 : 
      41                 : MARIA_KEY *_ma_sp_make_key(MARIA_HA *info, MARIA_KEY *ret_key, uint keynr,
      42                 :                            uchar *key, const uchar *record, my_off_t filepos,
      43                 :                            ulonglong trid)
      44               0 : {
      45                 :   HA_KEYSEG *keyseg;
      46               0 :   MARIA_KEYDEF *keyinfo = &info->s->keyinfo[keynr];
      47               0 :   uint len = 0;
      48                 :   const uchar *pos;
      49                 :   uint dlen;
      50                 :   uchar *dptr;
      51                 :   double mbr[SPDIMS * 2];
      52                 :   uint i;
      53               0 :   DBUG_ENTER("_ma_sp_make_key");
      54                 : 
      55               0 :   keyseg = &keyinfo->seg[-1];
      56               0 :   pos = record + keyseg->start;
      57               0 :   ret_key->data= key;
      58                 : 
      59               0 :   dlen = _ma_calc_blob_length(keyseg->bit_start, pos);
      60               0 :   memcpy_fixed(&dptr, pos + keyseg->bit_start, sizeof(char*));
      61               0 :   if (!dptr)
      62                 :   {
      63               0 :     my_errno= HA_ERR_NULL_IN_SPATIAL;
      64               0 :     DBUG_RETURN(0);
      65                 :   }
      66                 : 
      67               0 :   sp_mbr_from_wkb(dptr + 4, dlen - 4, SPDIMS, mbr);     /* SRID */
      68                 : 
      69               0 :   for (i = 0, keyseg = keyinfo->seg; keyseg->type; keyseg++, i++)
      70                 :   {
      71               0 :     uint length = keyseg->length, start= keyseg->start;
      72                 :     double val;
      73                 : 
      74               0 :     DBUG_ASSERT(length == 8);
      75               0 :     DBUG_ASSERT(!(start % 8));
      76               0 :     DBUG_ASSERT(start < sizeof(mbr));
      77               0 :     DBUG_ASSERT(keyseg->type == HA_KEYTYPE_DOUBLE);
      78                 : 
      79               0 :     val= mbr[start / sizeof (double)];
      80                 : #ifdef HAVE_ISNAN
      81               0 :     if (isnan(val))
      82                 :     {
      83               0 :       bzero(key, length);
      84               0 :       key+= length;
      85               0 :       len+= length;
      86               0 :       continue;
      87                 :     }
      88                 : #endif
      89                 : 
      90               0 :     if (keyseg->flag & HA_SWAP_KEY)
      91                 :     {
      92               0 :       mi_float8store(key, val);
      93                 :     }
      94                 :     else
      95                 :     {
      96               0 :       float8store((uchar *)key, val);
      97                 :     }
      98               0 :     key += length;
      99               0 :     len+= length;
     100                 :   }
     101               0 :   _ma_dpointer(info->s, key, filepos);
     102               0 :   ret_key->keyinfo= keyinfo;
     103               0 :   ret_key->data_length= len;
     104               0 :   ret_key->ref_length= info->s->rec_reflength;
     105               0 :   ret_key->flag= 0;
     106               0 :   if (_ma_have_versioning(info) && trid)
     107                 :   {
     108               0 :     ret_key->ref_length+= transid_store_packed(info,
     109                 :                                                key + ret_key->ref_length,
     110                 :                                                trid);
     111                 :   }
     112               0 :   DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, ret_key););
     113               0 :   DBUG_RETURN(ret_key);
     114                 : }
     115                 : 
     116                 : 
     117                 : /*
     118                 :   Calculate minimal bounding rectangle (mbr) of the spatial object
     119                 :   stored in "well-known binary representation" (wkb) format.
     120                 : */
     121                 : 
     122                 : static int sp_mbr_from_wkb(uchar *wkb, uint size, uint n_dims, double *mbr)
     123               0 : {
     124                 :   uint i;
     125                 : 
     126               0 :   for (i=0; i < n_dims; ++i)
     127                 :   {
     128               0 :     mbr[i * 2] = DBL_MAX;
     129               0 :     mbr[i * 2 + 1] = -DBL_MAX;
     130                 :   }
     131                 : 
     132               0 :   return sp_get_geometry_mbr(&wkb, wkb + size, n_dims, mbr, 1);
     133                 : }
     134                 : 
     135                 : /*
     136                 :   Add one point stored in wkb to mbr
     137                 : */
     138                 : 
     139                 : static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims,
     140                 :                                uchar byte_order __attribute__((unused)),
     141                 :                                double *mbr)
     142               0 : {
     143                 :   double ord;
     144               0 :   double *mbr_end= mbr + n_dims * 2;
     145                 : 
     146               0 :   while (mbr < mbr_end)
     147                 :   {
     148               0 :     if ((*wkb) > end - 8)
     149               0 :       return -1;
     150               0 :     float8get(ord, (const uchar*) *wkb);
     151               0 :     (*wkb)+= 8;
     152               0 :     if (ord < *mbr)
     153               0 :       *mbr= ord;
     154               0 :     mbr++;
     155               0 :     if (ord > *mbr)
     156               0 :       *mbr= ord;
     157               0 :     mbr++;
     158                 :   }
     159               0 :   return 0;
     160                 : }
     161                 : 
     162                 : 
     163                 : static int sp_get_point_mbr(uchar *(*wkb), uchar *end, uint n_dims,
     164                 :                            uchar byte_order, double *mbr)
     165               0 : {
     166               0 :   return sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr);
     167                 : }
     168                 : 
     169                 : 
     170                 : static int sp_get_linestring_mbr(uchar *(*wkb), uchar *end, uint n_dims,
     171                 :                                   uchar byte_order, double *mbr)
     172               0 : {
     173                 :   uint n_points;
     174                 : 
     175               0 :   n_points = uint4korr(*wkb);
     176               0 :   (*wkb) += 4;
     177               0 :   for (; n_points > 0; --n_points)
     178                 :   {
     179                 :     /* Add next point to mbr */
     180               0 :     if (sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr))
     181               0 :       return -1;
     182                 :   }
     183               0 :   return 0;
     184                 : }
     185                 : 
     186                 : 
     187                 : static int sp_get_polygon_mbr(uchar *(*wkb), uchar *end, uint n_dims,
     188                 :                                uchar byte_order, double *mbr)
     189               0 : {
     190                 :   uint n_linear_rings;
     191                 :   uint n_points;
     192                 : 
     193               0 :   n_linear_rings = uint4korr((*wkb));
     194               0 :   (*wkb) += 4;
     195                 : 
     196               0 :   for (; n_linear_rings > 0; --n_linear_rings)
     197                 :   {
     198               0 :     n_points = uint4korr((*wkb));
     199               0 :     (*wkb) += 4;
     200               0 :     for (; n_points > 0; --n_points)
     201                 :     {
     202                 :       /* Add next point to mbr */
     203               0 :       if (sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr))
     204               0 :         return -1;
     205                 :     }
     206                 :   }
     207               0 :   return 0;
     208                 : }
     209                 : 
     210                 : static int sp_get_geometry_mbr(uchar *(*wkb), uchar *end, uint n_dims,
     211                 :                               double *mbr, int top)
     212               0 : {
     213                 :   int res;
     214                 :   uchar byte_order;
     215                 :   uint wkb_type;
     216                 : 
     217               0 :   byte_order = *(*wkb);
     218               0 :   ++(*wkb);
     219                 : 
     220               0 :   wkb_type = uint4korr((*wkb));
     221               0 :   (*wkb) += 4;
     222                 : 
     223               0 :   switch ((enum wkbType) wkb_type)
     224                 :   {
     225                 :     case wkbPoint:
     226               0 :       res = sp_get_point_mbr(wkb, end, n_dims, byte_order, mbr);
     227               0 :       break;
     228                 :     case wkbLineString:
     229               0 :       res = sp_get_linestring_mbr(wkb, end, n_dims, byte_order, mbr);
     230               0 :       break;
     231                 :     case wkbPolygon:
     232               0 :       res = sp_get_polygon_mbr(wkb, end, n_dims, byte_order, mbr);
     233               0 :       break;
     234                 :     case wkbMultiPoint:
     235                 :     {
     236                 :       uint n_items;
     237               0 :       n_items = uint4korr((*wkb));
     238               0 :       (*wkb) += 4;
     239               0 :       for (; n_items > 0; --n_items)
     240                 :       {
     241               0 :         byte_order = *(*wkb);
     242               0 :         ++(*wkb);
     243               0 :         (*wkb) += 4;
     244               0 :         if (sp_get_point_mbr(wkb, end, n_dims, byte_order, mbr))
     245               0 :           return -1;
     246                 :       }
     247               0 :       res = 0;
     248               0 :       break;
     249                 :     }
     250                 :     case wkbMultiLineString:
     251                 :     {
     252                 :       uint n_items;
     253               0 :       n_items = uint4korr((*wkb));
     254               0 :       (*wkb) += 4;
     255               0 :       for (; n_items > 0; --n_items)
     256                 :       {
     257               0 :         byte_order = *(*wkb);
     258               0 :         ++(*wkb);
     259               0 :         (*wkb) += 4;
     260               0 :         if (sp_get_linestring_mbr(wkb, end, n_dims, byte_order, mbr))
     261               0 :           return -1;
     262                 :       }
     263               0 :       res = 0;
     264               0 :       break;
     265                 :     }
     266                 :     case wkbMultiPolygon:
     267                 :     {
     268                 :       uint n_items;
     269               0 :       n_items = uint4korr((*wkb));
     270               0 :       (*wkb) += 4;
     271               0 :       for (; n_items > 0; --n_items)
     272                 :       {
     273               0 :         byte_order = *(*wkb);
     274               0 :         ++(*wkb);
     275               0 :         (*wkb) += 4;
     276               0 :         if (sp_get_polygon_mbr(wkb, end, n_dims, byte_order, mbr))
     277               0 :           return -1;
     278                 :       }
     279               0 :       res = 0;
     280               0 :       break;
     281                 :     }
     282                 :     case wkbGeometryCollection:
     283                 :     {
     284                 :       uint n_items;
     285                 : 
     286               0 :       if (!top)
     287               0 :         return -1;
     288                 : 
     289               0 :       n_items = uint4korr((*wkb));
     290               0 :       (*wkb) += 4;
     291               0 :       for (; n_items > 0; --n_items)
     292                 :       {
     293               0 :         if (sp_get_geometry_mbr(wkb, end, n_dims, mbr, 0))
     294               0 :           return -1;
     295                 :       }
     296               0 :       res = 0;
     297               0 :       break;
     298                 :     }
     299                 :     default:
     300               0 :       res = -1;
     301                 :   }
     302               0 :   return res;
     303                 : }
     304                 : 
     305                 : #endif /*HAVE_SPATIAL*/

Generated by: LTP GCOV extension version 1.4