Loading myisam/mi_create.c +4 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, rec--; if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1) { /* NOTE1: here we change a field type FIELD_SKIP_ZERO -> FIELD_NORMAL */ rec->type=(int) FIELD_NORMAL; packed--; min_pack_length++; Loading myisam/rt_index.c +78 −28 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ int rtree_find_first(MI_INFO *info, uint keynr, uchar *key, uint key_length, /* Save searched key, include data pointer. The data pointer is required if the search_flag contains MBR_DATA. (minimum bounding rectangle) */ memcpy(info->first_mbr_key, key, keyinfo->keylength); info->last_rkey_length = key_length; Loading Loading @@ -540,16 +541,19 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, uint nod_flag; uchar *page_buf; int res; DBUG_ENTER("rtree_insert_req"); if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length + MI_MAX_KEY_BUFF))) { my_errno = HA_ERR_OUT_OF_MEM; return -1; DBUG_RETURN(-1); /* purecov: inspected */ } if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0)) goto err1; nod_flag = mi_test_if_nod(page_buf); DBUG_PRINT("rtree", ("page: %lu level: %d ins_level: %d nod_flag: %u", (ulong) page, level, ins_level, nod_flag)); if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */ (ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */ Loading Loading @@ -601,11 +605,11 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, ok: my_afree((byte*)page_buf); return res; DBUG_RETURN(res); err1: my_afree((byte*)page_buf); return -1; DBUG_RETURN(-1); /* purecov: inspected */ } Loading @@ -625,20 +629,21 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; int res; my_off_t new_page; DBUG_ENTER("rtree_insert_level"); if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) { int res; if ((old_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) == HA_OFFSET_ERROR) return -1; DBUG_RETURN(-1); info->buff_used = 1; mi_putint(info->buff, 2, 0); res = rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL); if (_mi_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff)) return 1; DBUG_RETURN(1); info->s->state.key_root[keynr] = old_root; return res; DBUG_RETURN(res); } switch ((res = rtree_insert_req(info, keyinfo, key, key_length, Loading @@ -655,11 +660,12 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, uchar *new_key; uint nod_flag = info->s->base.key_reflength; DBUG_PRINT("rtree", ("root was split, grow a new root")); if (!(new_root_buf = (uchar*)my_alloca((uint)keyinfo->block_length + MI_MAX_KEY_BUFF))) { my_errno = HA_ERR_OUT_OF_MEM; return -1; DBUG_RETURN(-1); /* purecov: inspected */ } mi_putint(new_root_buf, 2, nod_flag); Loading @@ -685,12 +691,14 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, DFLT_INIT_HITS, new_root_buf)) goto err1; info->s->state.key_root[keynr] = new_root; DBUG_PRINT("rtree", ("new root page: %lu level: %d nod_flag: %u", (ulong) new_root, 0, mi_test_if_nod(new_root_buf))); my_afree((byte*)new_root_buf); break; err1: my_afree((byte*)new_root_buf); return -1; DBUG_RETURN(-1); /* purecov: inspected */ } default: case -1: /* error */ Loading @@ -698,7 +706,7 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, break; } } return res; DBUG_RETURN(res); } Loading @@ -712,8 +720,10 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, int rtree_insert(MI_INFO *info, uint keynr, uchar *key, uint key_length) { return (!key_length || (rtree_insert_level(info, keynr, key, key_length, -1) == -1)) ? -1 : 0; DBUG_ENTER("rtree_insert"); DBUG_RETURN((!key_length || (rtree_insert_level(info, keynr, key, key_length, -1) == -1)) ? -1 : 0); } Loading @@ -728,6 +738,8 @@ int rtree_insert(MI_INFO *info, uint keynr, uchar *key, uint key_length) static int rtree_fill_reinsert_list(stPageList *ReinsertList, my_off_t page, int level) { DBUG_ENTER("rtree_fill_reinsert_list"); DBUG_PRINT("rtree", ("page: %lu level: %d", (ulong) page, level)); if (ReinsertList->n_pages == ReinsertList->m_pages) { ReinsertList->m_pages += REINSERT_BUFFER_INC; Loading @@ -739,10 +751,10 @@ static int rtree_fill_reinsert_list(stPageList *ReinsertList, my_off_t page, ReinsertList->pages[ReinsertList->n_pages].offs = page; ReinsertList->pages[ReinsertList->n_pages].level = level; ReinsertList->n_pages++; return 0; DBUG_RETURN(0); err1: return -1; DBUG_RETURN(-1); /* purecov: inspected */ } Loading @@ -766,15 +778,18 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, uint nod_flag; uchar *page_buf; int res; DBUG_ENTER("rtree_delete_req"); if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length))) { my_errno = HA_ERR_OUT_OF_MEM; return -1; DBUG_RETURN(-1); /* purecov: inspected */ } if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0)) goto err1; nod_flag = mi_test_if_nod(page_buf); DBUG_PRINT("rtree", ("page: %lu level: %d nod_flag: %u", (ulong) page, level, nod_flag)); k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); last = rt_PAGE_END(page_buf); Loading @@ -795,6 +810,7 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, if (*page_size + key_length >= rt_PAGE_MIN_SIZE(keyinfo->block_length)) { /* OK */ /* Calculate a new key value (MBR) for the shrinked block. */ if (rtree_set_key_mbr(info, keyinfo, k, key_length, _mi_kpos(nod_flag, k))) goto err1; Loading @@ -804,10 +820,23 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, } else { /* too small: delete key & add it descendant to reinsert list */ /* Too small: delete key & add it descendant to reinsert list. Store position and level of the block so that it can be accessed later for inserting the remaining keys. */ DBUG_PRINT("rtree", ("too small. move block to reinsert list")); if (rtree_fill_reinsert_list(ReinsertList, _mi_kpos(nod_flag, k), level + 1)) goto err1; /* Delete the key that references the block. This makes the block disappear from the index. Hence we need to insert its remaining keys later. Note: if the block is a branch block, we do not only remove this block, but the whole subtree. So we need to re-insert its keys on the same level later to reintegrate the subtrees. */ rtree_delete_key(info, page_buf, k, key_length, nod_flag); if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf)) Loading Loading @@ -867,11 +896,11 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, ok: my_afree((byte*)page_buf); return res; DBUG_RETURN(res); err1: my_afree((byte*)page_buf); return -1; DBUG_RETURN(-1); /* purecov: inspected */ } Loading @@ -889,12 +918,15 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length) stPageList ReinsertList; my_off_t old_root; MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; DBUG_ENTER("rtree_delete"); if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) { my_errno= HA_ERR_END_OF_FILE; return -1; DBUG_RETURN(-1); /* purecov: inspected */ } DBUG_PRINT("rtree", ("starting deletion at root page: %lu", (ulong) old_root)); ReinsertList.pages = NULL; ReinsertList.n_pages = 0; Loading @@ -903,12 +935,12 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length) switch (rtree_delete_req(info, keyinfo, key, key_length, old_root, &page_size, &ReinsertList, 0)) { case 2: case 2: /* empty */ { info->s->state.key_root[keynr] = HA_OFFSET_ERROR; return 0; DBUG_RETURN(0); } case 0: case 0: /* deleted */ { uint nod_flag; ulong i; Loading @@ -928,16 +960,34 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length) DFLT_INIT_HITS, page_buf, 0)) goto err1; nod_flag = mi_test_if_nod(page_buf); DBUG_PRINT("rtree", ("reinserting keys from " "page: %lu level: %d nod_flag: %u", (ulong) ReinsertList.pages[i].offs, ReinsertList.pages[i].level, nod_flag)); k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); last = rt_PAGE_END(page_buf); for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag)) { if (rtree_insert_level(info, keynr, k, key_length, ReinsertList.pages[i].level) == -1) int res; if ((res= rtree_insert_level(info, keynr, k, key_length, ReinsertList.pages[i].level)) == -1) { my_afree((byte*)page_buf); goto err1; } if (res) { ulong j; DBUG_PRINT("rtree", ("root has been split, adjust levels")); for (j= i; j < ReinsertList.n_pages; j++) { ReinsertList.pages[j].level++; DBUG_PRINT("rtree", ("keys from page: %lu now level: %d", (ulong) ReinsertList.pages[i].offs, ReinsertList.pages[i].level)); } } } my_afree((byte*)page_buf); if (_mi_dispose(info, keyinfo, ReinsertList.pages[i].offs, Loading @@ -964,20 +1014,20 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length) info->s->state.key_root[keynr] = new_root; } info->update= HA_STATE_DELETED; return 0; DBUG_RETURN(0); err1: return -1; DBUG_RETURN(-1); /* purecov: inspected */ } case 1: /* not found */ { my_errno = HA_ERR_KEY_NOT_FOUND; return -1; DBUG_RETURN(-1); /* purecov: inspected */ } default: case -1: /* error */ { return -1; DBUG_RETURN(-1); /* purecov: inspected */ } } } Loading myisam/rt_key.c +12 −5 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, { uint page_size = mi_getint(page_buf); uint nod_flag = mi_test_if_nod(page_buf); DBUG_ENTER("rtree_add_key"); if (page_size + key_length + info->s->base.rec_reflength <= keyinfo->block_length) Loading @@ -43,22 +44,26 @@ int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, if (nod_flag) { /* save key */ DBUG_ASSERT(_mi_kpos(nod_flag, key) < info->state->key_file_length); memcpy(rt_PAGE_END(page_buf), key - nod_flag, key_length + nod_flag); page_size += key_length + nod_flag; } else { /* save key */ DBUG_ASSERT(_mi_dpos(info, nod_flag, key + key_length + info->s->base.rec_reflength) < info->state->data_file_length + info->s->base.pack_reclength); memcpy(rt_PAGE_END(page_buf), key, key_length + info->s->base.rec_reflength); page_size += key_length + info->s->base.rec_reflength; } mi_putint(page_buf, page_size, nod_flag); return 0; DBUG_RETURN(0); } return (rtree_split_page(info, keyinfo, page_buf, key, key_length, new_page) ? -1 : 1); DBUG_RETURN((rtree_split_page(info, keyinfo, page_buf, key, key_length, new_page) ? -1 : 1)); } /* Loading Loading @@ -90,11 +95,13 @@ int rtree_delete_key(MI_INFO *info, uchar *page_buf, uchar *key, int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, uint key_length, my_off_t child_page) { DBUG_ENTER("rtree_set_key_mbr"); if (!_mi_fetch_keypage(info, keyinfo, child_page, DFLT_INIT_HITS, info->buff, 0)) return -1; DBUG_RETURN(-1); /* purecov: inspected */ return rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length); DBUG_RETURN(rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length)); } #endif /*HAVE_RTREE_KEYS*/ myisam/rt_split.c +5 −2 Original line number Diff line number Diff line Loading @@ -268,13 +268,15 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, info->s->base.rec_reflength); int max_keys = (mi_getint(page)-2) / (full_length); DBUG_ENTER("rtree_split_page"); DBUG_PRINT("rtree", ("splitting block")); n_dim = keyinfo->keysegs / 2; if (!(coord_buf= (double*) my_alloca(n_dim * 2 * sizeof(double) * (max_keys + 1 + 4) + sizeof(SplitStruct) * (max_keys + 1)))) return -1; DBUG_RETURN(-1); /* purecov: inspected */ task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4)); Loading Loading @@ -346,12 +348,13 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, else err_code= _mi_write_keypage(info, keyinfo, *new_page_offs, DFLT_INIT_HITS, new_page); DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs)); my_afree((byte*)new_page); split_err: my_afree((byte*) coord_buf); return err_code; DBUG_RETURN(err_code); } #endif /*HAVE_RTREE_KEYS*/ mysql-test/r/gis-rtree.result +552 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
myisam/mi_create.c +4 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, rec--; if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1) { /* NOTE1: here we change a field type FIELD_SKIP_ZERO -> FIELD_NORMAL */ rec->type=(int) FIELD_NORMAL; packed--; min_pack_length++; Loading
myisam/rt_index.c +78 −28 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ int rtree_find_first(MI_INFO *info, uint keynr, uchar *key, uint key_length, /* Save searched key, include data pointer. The data pointer is required if the search_flag contains MBR_DATA. (minimum bounding rectangle) */ memcpy(info->first_mbr_key, key, keyinfo->keylength); info->last_rkey_length = key_length; Loading Loading @@ -540,16 +541,19 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, uint nod_flag; uchar *page_buf; int res; DBUG_ENTER("rtree_insert_req"); if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length + MI_MAX_KEY_BUFF))) { my_errno = HA_ERR_OUT_OF_MEM; return -1; DBUG_RETURN(-1); /* purecov: inspected */ } if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0)) goto err1; nod_flag = mi_test_if_nod(page_buf); DBUG_PRINT("rtree", ("page: %lu level: %d ins_level: %d nod_flag: %u", (ulong) page, level, ins_level, nod_flag)); if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */ (ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */ Loading Loading @@ -601,11 +605,11 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, ok: my_afree((byte*)page_buf); return res; DBUG_RETURN(res); err1: my_afree((byte*)page_buf); return -1; DBUG_RETURN(-1); /* purecov: inspected */ } Loading @@ -625,20 +629,21 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; int res; my_off_t new_page; DBUG_ENTER("rtree_insert_level"); if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) { int res; if ((old_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) == HA_OFFSET_ERROR) return -1; DBUG_RETURN(-1); info->buff_used = 1; mi_putint(info->buff, 2, 0); res = rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL); if (_mi_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff)) return 1; DBUG_RETURN(1); info->s->state.key_root[keynr] = old_root; return res; DBUG_RETURN(res); } switch ((res = rtree_insert_req(info, keyinfo, key, key_length, Loading @@ -655,11 +660,12 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, uchar *new_key; uint nod_flag = info->s->base.key_reflength; DBUG_PRINT("rtree", ("root was split, grow a new root")); if (!(new_root_buf = (uchar*)my_alloca((uint)keyinfo->block_length + MI_MAX_KEY_BUFF))) { my_errno = HA_ERR_OUT_OF_MEM; return -1; DBUG_RETURN(-1); /* purecov: inspected */ } mi_putint(new_root_buf, 2, nod_flag); Loading @@ -685,12 +691,14 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, DFLT_INIT_HITS, new_root_buf)) goto err1; info->s->state.key_root[keynr] = new_root; DBUG_PRINT("rtree", ("new root page: %lu level: %d nod_flag: %u", (ulong) new_root, 0, mi_test_if_nod(new_root_buf))); my_afree((byte*)new_root_buf); break; err1: my_afree((byte*)new_root_buf); return -1; DBUG_RETURN(-1); /* purecov: inspected */ } default: case -1: /* error */ Loading @@ -698,7 +706,7 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, break; } } return res; DBUG_RETURN(res); } Loading @@ -712,8 +720,10 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, int rtree_insert(MI_INFO *info, uint keynr, uchar *key, uint key_length) { return (!key_length || (rtree_insert_level(info, keynr, key, key_length, -1) == -1)) ? -1 : 0; DBUG_ENTER("rtree_insert"); DBUG_RETURN((!key_length || (rtree_insert_level(info, keynr, key, key_length, -1) == -1)) ? -1 : 0); } Loading @@ -728,6 +738,8 @@ int rtree_insert(MI_INFO *info, uint keynr, uchar *key, uint key_length) static int rtree_fill_reinsert_list(stPageList *ReinsertList, my_off_t page, int level) { DBUG_ENTER("rtree_fill_reinsert_list"); DBUG_PRINT("rtree", ("page: %lu level: %d", (ulong) page, level)); if (ReinsertList->n_pages == ReinsertList->m_pages) { ReinsertList->m_pages += REINSERT_BUFFER_INC; Loading @@ -739,10 +751,10 @@ static int rtree_fill_reinsert_list(stPageList *ReinsertList, my_off_t page, ReinsertList->pages[ReinsertList->n_pages].offs = page; ReinsertList->pages[ReinsertList->n_pages].level = level; ReinsertList->n_pages++; return 0; DBUG_RETURN(0); err1: return -1; DBUG_RETURN(-1); /* purecov: inspected */ } Loading @@ -766,15 +778,18 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, uint nod_flag; uchar *page_buf; int res; DBUG_ENTER("rtree_delete_req"); if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length))) { my_errno = HA_ERR_OUT_OF_MEM; return -1; DBUG_RETURN(-1); /* purecov: inspected */ } if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0)) goto err1; nod_flag = mi_test_if_nod(page_buf); DBUG_PRINT("rtree", ("page: %lu level: %d nod_flag: %u", (ulong) page, level, nod_flag)); k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); last = rt_PAGE_END(page_buf); Loading @@ -795,6 +810,7 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, if (*page_size + key_length >= rt_PAGE_MIN_SIZE(keyinfo->block_length)) { /* OK */ /* Calculate a new key value (MBR) for the shrinked block. */ if (rtree_set_key_mbr(info, keyinfo, k, key_length, _mi_kpos(nod_flag, k))) goto err1; Loading @@ -804,10 +820,23 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, } else { /* too small: delete key & add it descendant to reinsert list */ /* Too small: delete key & add it descendant to reinsert list. Store position and level of the block so that it can be accessed later for inserting the remaining keys. */ DBUG_PRINT("rtree", ("too small. move block to reinsert list")); if (rtree_fill_reinsert_list(ReinsertList, _mi_kpos(nod_flag, k), level + 1)) goto err1; /* Delete the key that references the block. This makes the block disappear from the index. Hence we need to insert its remaining keys later. Note: if the block is a branch block, we do not only remove this block, but the whole subtree. So we need to re-insert its keys on the same level later to reintegrate the subtrees. */ rtree_delete_key(info, page_buf, k, key_length, nod_flag); if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf)) Loading Loading @@ -867,11 +896,11 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, ok: my_afree((byte*)page_buf); return res; DBUG_RETURN(res); err1: my_afree((byte*)page_buf); return -1; DBUG_RETURN(-1); /* purecov: inspected */ } Loading @@ -889,12 +918,15 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length) stPageList ReinsertList; my_off_t old_root; MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; DBUG_ENTER("rtree_delete"); if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) { my_errno= HA_ERR_END_OF_FILE; return -1; DBUG_RETURN(-1); /* purecov: inspected */ } DBUG_PRINT("rtree", ("starting deletion at root page: %lu", (ulong) old_root)); ReinsertList.pages = NULL; ReinsertList.n_pages = 0; Loading @@ -903,12 +935,12 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length) switch (rtree_delete_req(info, keyinfo, key, key_length, old_root, &page_size, &ReinsertList, 0)) { case 2: case 2: /* empty */ { info->s->state.key_root[keynr] = HA_OFFSET_ERROR; return 0; DBUG_RETURN(0); } case 0: case 0: /* deleted */ { uint nod_flag; ulong i; Loading @@ -928,16 +960,34 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length) DFLT_INIT_HITS, page_buf, 0)) goto err1; nod_flag = mi_test_if_nod(page_buf); DBUG_PRINT("rtree", ("reinserting keys from " "page: %lu level: %d nod_flag: %u", (ulong) ReinsertList.pages[i].offs, ReinsertList.pages[i].level, nod_flag)); k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); last = rt_PAGE_END(page_buf); for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag)) { if (rtree_insert_level(info, keynr, k, key_length, ReinsertList.pages[i].level) == -1) int res; if ((res= rtree_insert_level(info, keynr, k, key_length, ReinsertList.pages[i].level)) == -1) { my_afree((byte*)page_buf); goto err1; } if (res) { ulong j; DBUG_PRINT("rtree", ("root has been split, adjust levels")); for (j= i; j < ReinsertList.n_pages; j++) { ReinsertList.pages[j].level++; DBUG_PRINT("rtree", ("keys from page: %lu now level: %d", (ulong) ReinsertList.pages[i].offs, ReinsertList.pages[i].level)); } } } my_afree((byte*)page_buf); if (_mi_dispose(info, keyinfo, ReinsertList.pages[i].offs, Loading @@ -964,20 +1014,20 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length) info->s->state.key_root[keynr] = new_root; } info->update= HA_STATE_DELETED; return 0; DBUG_RETURN(0); err1: return -1; DBUG_RETURN(-1); /* purecov: inspected */ } case 1: /* not found */ { my_errno = HA_ERR_KEY_NOT_FOUND; return -1; DBUG_RETURN(-1); /* purecov: inspected */ } default: case -1: /* error */ { return -1; DBUG_RETURN(-1); /* purecov: inspected */ } } } Loading
myisam/rt_key.c +12 −5 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, { uint page_size = mi_getint(page_buf); uint nod_flag = mi_test_if_nod(page_buf); DBUG_ENTER("rtree_add_key"); if (page_size + key_length + info->s->base.rec_reflength <= keyinfo->block_length) Loading @@ -43,22 +44,26 @@ int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, if (nod_flag) { /* save key */ DBUG_ASSERT(_mi_kpos(nod_flag, key) < info->state->key_file_length); memcpy(rt_PAGE_END(page_buf), key - nod_flag, key_length + nod_flag); page_size += key_length + nod_flag; } else { /* save key */ DBUG_ASSERT(_mi_dpos(info, nod_flag, key + key_length + info->s->base.rec_reflength) < info->state->data_file_length + info->s->base.pack_reclength); memcpy(rt_PAGE_END(page_buf), key, key_length + info->s->base.rec_reflength); page_size += key_length + info->s->base.rec_reflength; } mi_putint(page_buf, page_size, nod_flag); return 0; DBUG_RETURN(0); } return (rtree_split_page(info, keyinfo, page_buf, key, key_length, new_page) ? -1 : 1); DBUG_RETURN((rtree_split_page(info, keyinfo, page_buf, key, key_length, new_page) ? -1 : 1)); } /* Loading Loading @@ -90,11 +95,13 @@ int rtree_delete_key(MI_INFO *info, uchar *page_buf, uchar *key, int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, uint key_length, my_off_t child_page) { DBUG_ENTER("rtree_set_key_mbr"); if (!_mi_fetch_keypage(info, keyinfo, child_page, DFLT_INIT_HITS, info->buff, 0)) return -1; DBUG_RETURN(-1); /* purecov: inspected */ return rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length); DBUG_RETURN(rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length)); } #endif /*HAVE_RTREE_KEYS*/
myisam/rt_split.c +5 −2 Original line number Diff line number Diff line Loading @@ -268,13 +268,15 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, info->s->base.rec_reflength); int max_keys = (mi_getint(page)-2) / (full_length); DBUG_ENTER("rtree_split_page"); DBUG_PRINT("rtree", ("splitting block")); n_dim = keyinfo->keysegs / 2; if (!(coord_buf= (double*) my_alloca(n_dim * 2 * sizeof(double) * (max_keys + 1 + 4) + sizeof(SplitStruct) * (max_keys + 1)))) return -1; DBUG_RETURN(-1); /* purecov: inspected */ task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4)); Loading Loading @@ -346,12 +348,13 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, else err_code= _mi_write_keypage(info, keyinfo, *new_page_offs, DFLT_INIT_HITS, new_page); DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs)); my_afree((byte*)new_page); split_err: my_afree((byte*) coord_buf); return err_code; DBUG_RETURN(err_code); } #endif /*HAVE_RTREE_KEYS*/
mysql-test/r/gis-rtree.result +552 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes