Drizzled Public API Documentation

row0ext.cc

00001 /*****************************************************************************
00002 
00003 Copyright (C) 2006, 2009, Innobase Oy. All Rights Reserved.
00004 
00005 This program is free software; you can redistribute it and/or modify it under
00006 the terms of the GNU General Public License as published by the Free Software
00007 Foundation; version 2 of the License.
00008 
00009 This program is distributed in the hope that it will be useful, but WITHOUT
00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00012 
00013 You should have received a copy of the GNU General Public License along with
00014 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
00015 St, Fifth Floor, Boston, MA 02110-1301 USA
00016 
00017 *****************************************************************************/
00018 
00019 /**************************************************/
00026 #include "row0ext.h"
00027 
00028 #ifdef UNIV_NONINL
00029 #include "row0ext.ic"
00030 #endif
00031 
00032 #include "btr0cur.h"
00033 
00034 /********************************************************************/
00036 static
00037 void
00038 row_ext_cache_fill(
00039 /*===============*/
00040   row_ext_t*  ext,  
00041   ulint   i,  
00042   ulint   zip_size,
00043   const dfield_t* dfield) 
00044 {
00045   const byte* field = static_cast<const byte *>(dfield_get_data(dfield));
00046   ulint   f_len = dfield_get_len(dfield);
00047   byte*   buf = ext->buf + i * REC_MAX_INDEX_COL_LEN;
00048 
00049   ut_ad(i < ext->n_ext);
00050   ut_ad(dfield_is_ext(dfield));
00051   ut_a(f_len >= BTR_EXTERN_FIELD_REF_SIZE);
00052 
00053   if (UNIV_UNLIKELY(!memcmp(field_ref_zero,
00054           field + f_len - BTR_EXTERN_FIELD_REF_SIZE,
00055           BTR_EXTERN_FIELD_REF_SIZE))) {
00056     /* The BLOB pointer is not set: we cannot fetch it */
00057     ext->len[i] = 0;
00058   } else {
00059     /* Fetch at most REC_MAX_INDEX_COL_LEN of the column.
00060     The column should be non-empty.  However,
00061     trx_rollback_or_clean_all_recovered() may try to
00062     access a half-deleted BLOB if the server previously
00063     crashed during the execution of
00064     btr_free_externally_stored_field(). */
00065     ext->len[i] = btr_copy_externally_stored_field_prefix(
00066       buf, REC_MAX_INDEX_COL_LEN, zip_size, field, f_len);
00067   }
00068 }
00069 
00070 /********************************************************************/
00073 UNIV_INTERN
00074 row_ext_t*
00075 row_ext_create(
00076 /*===========*/
00077   ulint   n_ext,  
00078   const ulint*  ext,  
00082   const dtuple_t* tuple,  
00088   ulint   zip_size,
00089   mem_heap_t* heap) 
00090 {
00091   ulint   i;
00092   row_ext_t*  ret = static_cast<row_ext_t *>(mem_heap_alloc(heap, (sizeof *ret)
00093                + (n_ext - 1) * sizeof ret->len));
00094 
00095   ut_ad(ut_is_2pow(zip_size));
00096   ut_ad(zip_size <= UNIV_PAGE_SIZE);
00097 
00098   ret->n_ext = n_ext;
00099   ret->ext = ext;
00100   ret->buf = static_cast<byte *>(mem_heap_alloc(heap, n_ext * REC_MAX_INDEX_COL_LEN));
00101 #ifdef UNIV_DEBUG
00102   memset(ret->buf, 0xaa, n_ext * REC_MAX_INDEX_COL_LEN);
00103   UNIV_MEM_ALLOC(ret->buf, n_ext * REC_MAX_INDEX_COL_LEN);
00104 #endif
00105 
00106   /* Fetch the BLOB prefixes */
00107   for (i = 0; i < n_ext; i++) {
00108     const dfield_t* dfield;
00109 
00110     dfield = dtuple_get_nth_field(tuple, ext[i]);
00111     row_ext_cache_fill(ret, i, zip_size, dfield);
00112   }
00113 
00114   return(ret);
00115 }