void decode(double *dest, const uchar *source) { MRN_DBUG_ENTER_FUNCTION(); #ifdef MRN_DEST_IS_POINTER float8get(dest, source); #else double value; float8get(value, source); *dest = value; #endif DBUG_VOID_RETURN; }
/* {{{ ps_fetch_double */ static void ps_fetch_double(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { double value; DBG_ENTER("ps_fetch_double"); float8get(value, *row); ZVAL_DOUBLE(zv, value); (*row)+= 8; DBG_INF_FMT("value=%f", value); DBG_VOID_RETURN; }
/* {{{ ps_fetch_double */ static void ps_fetch_double(MYSQL_BIND *r_param, const MYSQL_FIELD * field , unsigned char **row) { switch (r_param->buffer_type) { case MYSQL_TYPE_DOUBLE: { double *value= (double *)r_param->buffer; float8get(*value, *row); r_param->buffer_length= 8; } break; default: { double value; float8get(value, *row); convert_from_double(r_param, field, value, sizeof(double)); } break; } (*row)+= 8; }
static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims, uchar byte_order __attribute__((unused)), double *mbr) { double ord; double *mbr_end= mbr + n_dims * 2; while (mbr < mbr_end) { if ((*wkb) > end - 8) return -1; float8get(ord, (const uchar*) *wkb); (*wkb)+= 8; if (ord < *mbr) *mbr= ord; mbr++; if (ord > *mbr) *mbr= ord; mbr++; } return 0; }
MARIA_KEY *_ma_make_key(MARIA_HA *info, MARIA_KEY *int_key, uint keynr, uchar *key, const uchar *record, MARIA_RECORD_POS filepos, ulonglong trid) { const uchar *pos; reg1 HA_KEYSEG *keyseg; my_bool is_ft; DBUG_ENTER("_ma_make_key"); int_key->data= key; int_key->flag= 0; /* Always return full key */ int_key->keyinfo= info->s->keyinfo + keynr; is_ft= int_key->keyinfo->flag & HA_FULLTEXT; for (keyseg= int_key->keyinfo->seg ; keyseg->type ;keyseg++) { enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type; uint length=keyseg->length; uint char_length; CHARSET_INFO *cs=keyseg->charset; if (keyseg->null_bit) { if (record[keyseg->null_pos] & keyseg->null_bit) { *key++= 0; /* NULL in key */ continue; } *key++=1; /* Not NULL */ } char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length); pos= record+keyseg->start; if (type == HA_KEYTYPE_BIT) { if (keyseg->bit_length) { uchar bits= get_rec_bits(record + keyseg->bit_pos, keyseg->bit_start, keyseg->bit_length); *key++= (char) bits; length--; } memcpy(key, pos, length); key+= length; continue; } if (keyseg->flag & HA_SPACE_PACK) { if (type != HA_KEYTYPE_NUM) { length= (uint) cs->cset->lengthsp(cs, (const char*)pos, length); } else { const uchar *end= pos + length; while (pos < end && pos[0] == ' ') pos++; length= (uint) (end-pos); } FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy(key, pos, (size_t) char_length); key+=char_length; continue; } if (keyseg->flag & HA_VAR_LENGTH_PART) { uint pack_length= (keyseg->bit_start == 1 ? 1 : 2); uint tmp_length= (pack_length == 1 ? (uint) *pos : uint2korr(pos)); pos+= pack_length; /* Skip VARCHAR length */ set_if_smaller(length,tmp_length); FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy(key,pos,(size_t) char_length); key+= char_length; continue; } else if (keyseg->flag & HA_BLOB_PART) { uint tmp_length= _ma_calc_blob_length(keyseg->bit_start,pos); uchar *blob_pos; memcpy(&blob_pos, pos+keyseg->bit_start,sizeof(char*)); set_if_smaller(length,tmp_length); FIX_LENGTH(cs, blob_pos, length, char_length); store_key_length_inc(key,char_length); memcpy(key, blob_pos, (size_t) char_length); key+= char_length; continue; } else if (keyseg->flag & HA_SWAP_KEY) { /* Numerical column */ #ifdef HAVE_ISNAN if (type == HA_KEYTYPE_FLOAT) { float nr; float4get(nr,pos); if (isnan(nr)) { /* Replace NAN with zero */ bzero(key,length); key+=length; continue; } } else if (type == HA_KEYTYPE_DOUBLE) { double nr; float8get(nr,pos); if (isnan(nr)) { bzero(key,length); key+=length; continue; } } #endif pos+=length; while (length--) { *key++ = *--pos; } continue; } FIX_LENGTH(cs, pos, length, char_length); memcpy(key, pos, char_length); if (length > char_length) cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' '); key+= length; } _ma_dpointer(info->s, key, filepos); int_key->data_length= (key - int_key->data); int_key->ref_length= info->s->rec_reflength; int_key->flag= 0; if (_ma_have_versioning(info) && trid) { int_key->ref_length+= transid_store_packed(info, key + int_key->ref_length, (TrID) trid); int_key->flag|= SEARCH_USER_KEY_HAS_TRANSID; } DBUG_PRINT("exit",("keynr: %d",keynr)); DBUG_DUMP_KEY("key", int_key); DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, int_key););
uint _mi_make_key(MI_INFO *info, uint keynr, uchar *key, const uchar *record, my_off_t filepos) { uchar *pos; uchar *start; HA_KEYSEG *keyseg; my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT; DBUG_ENTER("_mi_make_key"); if (info->s->keyinfo[keynr].flag & HA_SPATIAL) { /* TODO: nulls processing */ DBUG_RETURN(sp_make_key(info,keynr,key,record,filepos)); } start=key; for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++) { enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type; uint length=keyseg->length; uint char_length; const CHARSET_INFO *cs= keyseg->charset; if (keyseg->null_bit) { if (record[keyseg->null_pos] & keyseg->null_bit) { *key++= 0; /* NULL in key */ continue; } *key++=1; /* Not NULL */ } char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length); pos= (uchar*) record+keyseg->start; if (type == HA_KEYTYPE_BIT) { if (keyseg->bit_length) { uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos, keyseg->bit_start, keyseg->bit_length); *key++= bits; length--; } memcpy((uchar*) key, pos, length); key+= length; continue; } if (keyseg->flag & HA_SPACE_PACK) { if (type != HA_KEYTYPE_NUM) { length= cs->cset->lengthsp(cs, (char*) pos, length); } else { uchar *end= pos + length; while (pos < end && pos[0] == ' ') pos++; length=(uint) (end-pos); } FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((uchar*) key,(uchar*) pos,(size_t) char_length); key+=char_length; continue; } if (keyseg->flag & HA_VAR_LENGTH_PART) { uint pack_length= (keyseg->bit_start == 1 ? 1 : 2); uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos)); pos+= pack_length; /* Skip VARCHAR length */ set_if_smaller(length,tmp_length); FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((uchar*) key,(uchar*) pos,(size_t) char_length); key+= char_length; continue; } else if (keyseg->flag & HA_BLOB_PART) { uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos); memcpy(&pos,pos+keyseg->bit_start,sizeof(char*)); set_if_smaller(length,tmp_length); FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((uchar*) key,(uchar*) pos,(size_t) char_length); key+= char_length; continue; } else if (keyseg->flag & HA_SWAP_KEY) { /* Numerical column */ if (type == HA_KEYTYPE_FLOAT) { float nr; float4get(&nr,pos); if (my_isnan(nr)) { /* Replace NAN with zero */ memset(key, 0, length); key+=length; continue; } } else if (type == HA_KEYTYPE_DOUBLE) { double nr; float8get(&nr,pos); if (my_isnan(nr)) { memset(key, 0, length); key+=length; continue; } } pos+=length; while (length--) { *key++ = *--pos; } continue; } FIX_LENGTH(cs, pos, length, char_length); memcpy((uchar*) key, pos, char_length); if (length > char_length) cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' '); key+= length; } _mi_dpointer(info,key,filepos); DBUG_PRINT("exit",("keynr: %d",keynr)); DBUG_DUMP("key",(uchar*) start,(uint) (key-start)+keyseg->length); DBUG_EXECUTE("key", _mi_print_key(DBUG_FILE,info->s->keyinfo[keynr].seg,start, (uint) (key-start)););
uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec, uchar *recpos) { uchar *start_key= key; HA_KEYSEG *seg, *endseg; for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++) { uint char_length; if (seg->null_bit) { if (!(*key++= 1 - MY_TEST(rec[seg->null_pos] & seg->null_bit))) continue; } if (seg->flag & HA_SWAP_KEY) { uint length= seg->length; uchar *pos= (uchar*) rec + seg->start; DBUG_ASSERT(seg->type != HA_KEYTYPE_BIT); #ifdef HAVE_ISNAN if (seg->type == HA_KEYTYPE_FLOAT) { float nr; float4get(nr, pos); if (isnan(nr)) { /* Replace NAN with zero */ bzero(key, length); key+= length; continue; } } else if (seg->type == HA_KEYTYPE_DOUBLE) { double nr; float8get(nr, pos); if (isnan(nr)) { bzero(key, length); key+= length; continue; } } #endif pos+= length; while (length--) { *key++= *--pos; } continue; } if (seg->flag & HA_VAR_LENGTH_PART) { uchar *pos= (uchar*) rec + seg->start; uint length= seg->length; uint pack_length= seg->bit_start; uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos)); CHARSET_INFO *cs= seg->charset; char_length= length/cs->mbmaxlen; pos+= pack_length; /* Skip VARCHAR length */ set_if_smaller(length,tmp_length); FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((uchar*) key,(uchar*) pos,(size_t) char_length); key+= char_length; continue; } char_length= seg->length; if (seg->charset->mbmaxlen > 1) { char_length= my_charpos(seg->charset, rec + seg->start, rec + seg->start + char_length, char_length / seg->charset->mbmaxlen); set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ if (char_length < seg->length) seg->charset->cset->fill(seg->charset, (char*) key + char_length, seg->length - char_length, ' '); } if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) { *key++= get_rec_bits(rec + seg->bit_pos, seg->bit_start, seg->bit_length); char_length--; } memcpy(key, rec + seg->start, (size_t) char_length); key+= seg->length; } memcpy(key, &recpos, sizeof(uchar*)); return (uint) (key - start_key); }
uint _mi_make_key(register MI_INFO * info, uint keynr, uchar * key, const byte * record, my_off_t filepos) { byte *pos, *end; uchar *start; reg1 MI_KEYSEG *keyseg; DBUG_ENTER("_mi_make_key"); start = key; for (keyseg = info->s->keyinfo[keynr].seg; keyseg->type; keyseg++) { enum ha_base_keytype type = (enum ha_base_keytype)keyseg->type; uint length = keyseg->length; if (keyseg->null_bit) { if (record[keyseg->null_pos] & keyseg->null_bit) { *key++ = 0; /* NULL in key */ continue; } *key++ = 1; /* Not NULL */ } pos = (byte *) record + keyseg->start; if (keyseg->flag & HA_SPACE_PACK) { end = pos + length; if (type != HA_KEYTYPE_NUM) { while (end > pos && end[-1] == ' ') end--; } else { while (pos < end && pos[0] == ' ') pos++; } length = (uint) (end - pos); store_key_length_inc(key, length); memcpy((byte *) key, (byte *) pos, (size_t) length); key += length; continue; } if (keyseg->flag & HA_VAR_LENGTH) { uint tmp_length = uint2korr(pos); pos += 2; /* Skip VARCHAR length */ set_if_smaller(length, tmp_length); store_key_length_inc(key, length); } else if (keyseg->flag & HA_BLOB_PART) { uint tmp_length = _mi_calc_blob_length(keyseg->bit_start, pos); memcpy_fixed((byte *) & pos, pos + keyseg->bit_start, sizeof(char *)); set_if_smaller(length, tmp_length); store_key_length_inc(key, length); } else if (keyseg->flag & HA_SWAP_KEY) { /* Numerical column */ #ifdef NAN_TEST float float_nr; double dbl_nr; if (type == HA_KEYTYPE_FLOAT) { float_nr = float4get(pos); if (float_nr == (float)FLT_MAX) { float_nr = (float)FLT_MAX; pos = (byte *) & float_nr; } } else if (type == HA_KEYTYPE_DOUBLE) { dbl_nr = float8get(key); if (dbl_nr == DBL_MAX) { dbl_nr = DBL_MAX; pos = (byte *) & dbl_nr; } } #endif pos += length; while (length--) { *key++ = *--pos; } continue; } memcpy((byte *) key, pos, length); key += length; } _mi_dpointer(info, key, filepos); DBUG_PRINT("exit", ("keynr: %d", keynr)); DBUG_DUMP("key", (byte *) start, (uint) (key - start) + keyseg->length); DBUG_EXECUTE("key", _mi_print_key(DBUG_FILE, info->s->keyinfo[keynr].seg, start, (uint) (key - start)); );
/************************************************** read data in binary type **************************************************/ int mysac_decode_binary_row(char *buf, int packet_len, MYSAC_RES *res, MYSAC_ROWS *row) { int j; int i; char nul; unsigned long len; int tmp_len; char *wh; char _null_ptr[16]; char *null_ptr; unsigned char bit; wh = buf; null_ptr = _null_ptr; bit = 4; /* first 2 bits are reserved */ /* first bit is unused */ i = 1; /* skip null bits */ tmp_len = ( (res->nb_cols + 9) / 8 ); if (i + tmp_len > packet_len) return -1; memcpy(_null_ptr, &buf[i], tmp_len); i += tmp_len; for (j = 0; j < res->nb_cols; j++) { /* We should set both row_ptr and is_null to be able to see nulls in mysql_stmt_fetch_column. This is because is_null may point to user data which can be overwritten between mysql_stmt_fetch and mysql_stmt_fetch_column, and in this case nullness of column will be lost. See mysql_stmt_fetch_column for details. */ if ( (*null_ptr & bit) != 0 ) { /* do nothing */ } else { switch (res->cols[j].type) { /* read null */ case MYSQL_TYPE_NULL: row->data[j].blob = NULL; /* read blob */ case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: /* decimal ? maybe for very big num ... crypto key ? */ case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: /* .... */ case MYSQL_TYPE_BIT: /* read text */ case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_VARCHAR: /* read date */ case MYSQL_TYPE_NEWDATE: tmp_len = my_lcb(&buf[i], &len, &nul, packet_len-i); if (tmp_len == -1) return -1; i += tmp_len; if (i + len > (unsigned int)packet_len) return -1; if (nul == 1) row->data[j].blob = NULL; else { memmove(wh, &buf[i], len); row->data[j].blob = wh; row->data[j].blob[len] = '\0'; i += len; wh += len + 1; } row->lengths[j] = len; break; case MYSQL_TYPE_TINY: if (i > packet_len - 1) return -1; row->data[j].stiny = buf[i]; i++; break; case MYSQL_TYPE_SHORT: if (i > packet_len - 2) return -1; row->data[j].ssmall = sint2korr(&buf[i]); i += 2; break; case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: if (i > packet_len - 4) return -1; row->data[j].sint = sint4korr(&buf[i]); i += 4; break; case MYSQL_TYPE_LONGLONG: if (i > packet_len - 8) return -1; row->data[j].sbigint = sint8korr(&buf[i]); i += 8; break; case MYSQL_TYPE_FLOAT: if (i > packet_len - 4) return -1; float4get(row->data[j].mfloat, &buf[i]); i += 4; break; case MYSQL_TYPE_DOUBLE: if (i > packet_len - 8) return -1; float8get(row->data[j].mdouble, &buf[i]); i += 8; break; /* libmysql/libmysql.c:3370 * static void read_binary_time(MYSQL_TIME *tm, uchar **pos) */ case MYSQL_TYPE_TIME: tmp_len = my_lcb(&buf[i], &len, &nul, packet_len-i); if (tmp_len == -1) return -1; i += tmp_len; if (i + len > (unsigned int)packet_len) return -1; if (nul == 1) row->data[j].blob = NULL; if (len > 0) { row->data[j].tv.tv_sec = ( uint4korr(&buf[i+1]) * 86400 ) + ( buf[i+5] * 3600 ) + ( buf[i+6] * 60 ) + buf[i+7]; if (buf[i] != 0) row->data[j].tv.tv_sec = - row->data[j].tv.tv_sec; if (len > 8) row->data[j].tv.tv_usec = uint4korr(&buf[i+8]); else row->data[j].tv.tv_usec = 0; } i += len; break; case MYSQL_TYPE_YEAR: row->data[j].tm->tm_year = uint2korr(&buf[i]) - 1900; row->data[j].tm->tm_mday = 1; i += 2; break; /* libmysql/libmysql.c:3400 * static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos) */ case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATETIME: tmp_len = my_lcb(&buf[i], &len, &nul, packet_len-i); if (tmp_len == -1) return -1; i += tmp_len; if (i + len > (unsigned int)packet_len) return -1; if (nul == 1) row->data[j].blob = NULL; row->data[j].tm->tm_year = uint2korr(&buf[i+0]) - 1900; row->data[j].tm->tm_mon = buf[i+2] - 1; row->data[j].tm->tm_mday = buf[i+3]; if (len > 4) { row->data[j].tm->tm_hour = buf[i+4]; row->data[j].tm->tm_min = buf[i+5]; row->data[j].tm->tm_sec = buf[i+6]; } if (len > 7) { /* les microsecondes ... */ } i += len; break; /* libmysql/libmysql.c:3430 * static void read_binary_date(MYSQL_TIME *tm, uchar **pos) */ case MYSQL_TYPE_DATE: tmp_len = my_lcb(&buf[i], &len, &nul, packet_len-i); if (tmp_len == -1) return -1; i += tmp_len; if (i + len > (unsigned int)packet_len) return -1; if (nul == 1) row->data[j].blob = NULL; row->data[j].tm->tm_year = uint2korr(&buf[i+0]) - 1900; row->data[j].tm->tm_mon = buf[i+2] - 1; row->data[j].tm->tm_mday = buf[i+3]; i += len; break; case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: case MYSQL_TYPE_GEOMETRY: break; } } /* To next bit */ bit <<= 1; /* To next byte */ if ( (bit & 255) == 0 ) { bit = 1; null_ptr++; } } return wh - buf; }