size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags) { size_t writtenbytes =0; my_off_t seekptr; #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) uint errors; #endif DBUG_ENTER("my_fwrite"); DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %d", (long) stream, (long) Buffer, (uint) Count, MyFlags)); #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) errors=0; #endif seekptr= ftell(stream); for (;;) { size_t written; if ((written = (size_t) fwrite((char*) Buffer,sizeof(char), Count, stream)) != Count) { DBUG_PRINT("error",("Write only %d bytes", (int) writtenbytes)); my_errno=errno; if (written != (size_t) -1) { seekptr+=written; Buffer+=written; writtenbytes+=written; Count-=written; } #ifdef EINTR if (errno == EINTR) { (void) my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0)); continue; } #endif #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) if (my_thread_var->abort) MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */ if ((errno == ENOSPC || errno == EDQUOT) && (MyFlags & MY_WAIT_IF_FULL)) { wait_for_free_space("[stream]", errors); errors++; (void) my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0)); continue; } #endif if (ferror(stream) || (MyFlags & (MY_NABP | MY_FNABP))) { if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG), my_filename(my_fileno(stream)),errno); } writtenbytes= (size_t) -1; /* Return that we got error */ break; } } if (MyFlags & (MY_NABP | MY_FNABP)) writtenbytes= 0; /* Everything OK */ else writtenbytes+= written; break; } DBUG_RETURN(writtenbytes); } /* my_fwrite */
void mrn_get_partition_info(const char *table_name, uint table_name_length, const TABLE *table, partition_element **part_elem, partition_element **sub_elem) { char tmp_name[FN_LEN]; partition_info *part_info = table->part_info; partition_element *tmp_part_elem = NULL, *tmp_sub_elem = NULL; bool tmp_flg = FALSE, tmp_find_flg = FALSE; MRN_DBUG_ENTER_FUNCTION(); *part_elem = NULL; *sub_elem = NULL; if (!part_info) DBUG_VOID_RETURN; if (table_name && !memcmp(table_name + table_name_length - 5, "#TMP#", 5)) tmp_flg = TRUE; DBUG_PRINT("info", ("mroonga table_name=%s", table_name)); List_iterator<partition_element> part_it(part_info->partitions); while ((*part_elem = part_it++)) { if ((*part_elem)->subpartitions.elements) { List_iterator<partition_element> sub_it((*part_elem)->subpartitions); while ((*sub_elem = sub_it++)) { create_subpartition_name(tmp_name, table->s->path.str, (*part_elem)->partition_name, (*sub_elem)->partition_name, NORMAL_PART_NAME); DBUG_PRINT("info", ("mroonga tmp_name=%s", tmp_name)); if (table_name && !memcmp(table_name, tmp_name, table_name_length + 1)) DBUG_VOID_RETURN; if ( tmp_flg && table_name && *(tmp_name + table_name_length - 5) == '\0' && !memcmp(table_name, tmp_name, table_name_length - 5) ) { tmp_part_elem = *part_elem; tmp_sub_elem = *sub_elem; tmp_flg = FALSE; tmp_find_flg = TRUE; } } } else { create_partition_name(tmp_name, table->s->path.str, (*part_elem)->partition_name, NORMAL_PART_NAME, TRUE); DBUG_PRINT("info", ("mroonga tmp_name=%s", tmp_name)); if (table_name && !memcmp(table_name, tmp_name, table_name_length + 1)) DBUG_VOID_RETURN; if ( tmp_flg && table_name && *(tmp_name + table_name_length - 5) == '\0' && !memcmp(table_name, tmp_name, table_name_length - 5) ) { tmp_part_elem = *part_elem; tmp_flg = FALSE; tmp_find_flg = TRUE; } } } if (tmp_find_flg) { *part_elem = tmp_part_elem; *sub_elem = tmp_sub_elem; DBUG_PRINT("info", ("mroonga tmp find")); DBUG_VOID_RETURN; } *part_elem = NULL; *sub_elem = NULL; DBUG_PRINT("info", ("mroonga no hit")); DBUG_VOID_RETURN; }
int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i) { int error; char *param_string = NULL; #if MYSQL_VERSION_ID >= 50500 int title_length; char *sprit_ptr[2]; char *tmp_ptr, *start_ptr; #endif THD *thd = current_thd; MRN_DBUG_ENTER_FUNCTION(); #if MYSQL_VERSION_ID >= 50500 if (key_info->comment.length == 0) { if (share->key_tokenizer[i]) { my_free(share->key_tokenizer[i]); } share->key_tokenizer[i] = mrn_my_strdup(mrn_default_tokenizer, MYF(MY_WME)); if (!share->key_tokenizer[i]) { error = HA_ERR_OUT_OF_MEM; goto error; } share->key_tokenizer_length[i] = strlen(share->key_tokenizer[i]); DBUG_RETURN(0); } DBUG_PRINT("info", ("mroonga create comment string")); if ( !(param_string = mrn_my_strndup(key_info->comment.str, key_info->comment.length, MYF(MY_WME))) ) { error = HA_ERR_OUT_OF_MEM; goto error_alloc_param_string; } DBUG_PRINT("info", ("mroonga comment string=%s", param_string)); sprit_ptr[0] = param_string; while (sprit_ptr[0]) { if ((sprit_ptr[1] = strchr(sprit_ptr[0], ','))) { *sprit_ptr[1] = '\0'; sprit_ptr[1]++; } tmp_ptr = sprit_ptr[0]; sprit_ptr[0] = sprit_ptr[1]; while (*tmp_ptr == ' ' || *tmp_ptr == '\r' || *tmp_ptr == '\n' || *tmp_ptr == '\t') tmp_ptr++; if (*tmp_ptr == '\0') continue; title_length = 0; start_ptr = tmp_ptr; while (*start_ptr != ' ' && *start_ptr != '\'' && *start_ptr != '"' && *start_ptr != '\0' && *start_ptr != '\r' && *start_ptr != '\n' && *start_ptr != '\t') { title_length++; start_ptr++; } switch (title_length) { case 5: MRN_PARAM_STR_LIST("table", index_table, i); break; case 6: push_warning_printf(thd, MRN_SEVERITY_WARNING, ER_WARN_DEPRECATED_SYNTAX, ER(ER_WARN_DEPRECATED_SYNTAX), "parser", "tokenizer"); MRN_PARAM_STR_LIST("parser", key_tokenizer, i); break; case 9: MRN_PARAM_STR_LIST("tokenizer", key_tokenizer, i); break; default: break; } } #endif if (!share->key_tokenizer[i]) { share->key_tokenizer[i] = mrn_my_strdup(mrn_default_tokenizer, MYF(MY_WME)); if (!share->key_tokenizer[i]) { error = HA_ERR_OUT_OF_MEM; goto error; } share->key_tokenizer_length[i] = strlen(share->key_tokenizer[i]); } if (param_string) my_free(param_string); DBUG_RETURN(0); error: if (param_string) my_free(param_string); #if MYSQL_VERSION_ID >= 50500 error_alloc_param_string: #endif DBUG_RETURN(error); }
/* TODO: Add option --verify to mysqld to be able to change verification mode */ struct st_VioSSLAcceptorFd* new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, const char *cipher) { int verify = (SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE); struct st_VioSSLAcceptorFd* ptr; int result; DH *dh=NULL; DBUG_ENTER("new_VioSSLAcceptorFd"); DBUG_PRINT("enter", ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s", key_file, cert_file, ca_path, ca_file, cipher)); ptr= ((struct st_VioSSLAcceptorFd*) my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0))); ptr->ssl_context=0; ptr->ssl_method=0; /* FIXME: constants! */ ptr->session_id_context= ptr; if (!ssl_algorithms_added) { DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()")); ssl_algorithms_added = TRUE; OpenSSL_add_all_algorithms(); } if (!ssl_error_strings_loaded) { DBUG_PRINT("info", ("todo: SSL_load_error_strings()")); ssl_error_strings_loaded = TRUE; SSL_load_error_strings(); } ptr->ssl_method= TLSv1_server_method(); ptr->ssl_context= SSL_CTX_new(ptr->ssl_method); if (ptr->ssl_context == 0) { DBUG_PRINT("error", ("SSL_CTX_new failed")); report_errors(); goto ctor_failure; } if (cipher) { result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher); DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result)); } /* SSL_CTX_set_quiet_shutdown(ctx,1); */ SSL_CTX_sess_set_cache_size(ptr->ssl_context,128); /* DH? */ SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback); SSL_CTX_set_session_id_context(ptr->ssl_context, (const uchar*) &(ptr->session_id_context), sizeof(ptr->session_id_context)); /* SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); */ if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1) { DBUG_PRINT("error", ("vio_set_cert_stuff failed")); report_errors(); goto ctor_failure; } if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file, ca_path) == 0) { DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); if (SSL_CTX_set_default_verify_paths(ptr->ssl_context)==0) { DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed")); report_errors(); goto ctor_failure; } } /* DH stuff */ dh=get_dh512(); SSL_CTX_set_tmp_dh(ptr->ssl_context,dh); DH_free(dh); DBUG_RETURN(ptr); ctor_failure: DBUG_PRINT("exit", ("there was an error")); my_free((gptr) ptr,MYF(0)); DBUG_RETURN(0); }
MY_DIR *my_dir(const char *path, myf MyFlags) { char *buffer; MY_DIR *result= 0; FILEINFO finfo; DYNAMIC_ARRAY *dir_entries_storage; MEM_ROOT *names_storage; #ifdef __BORLANDC__ struct ffblk find; #else struct _finddata_t find; #endif ushort mode; char tmp_path[FN_REFLEN],*tmp_file,attrib; #ifdef _WIN64 __int64 handle; #else long handle; #endif DBUG_ENTER("my_dir"); DBUG_PRINT("my",("path: '%s' stat: %d MyFlags: %d",path,MyFlags)); /* Put LIB-CHAR as last path-character if not there */ tmp_file=tmp_path; if (!*path) *tmp_file++ ='.'; /* From current dir */ tmp_file= strnmov(tmp_file, path, FN_REFLEN-5); if (tmp_file[-1] == FN_DEVCHAR) *tmp_file++= '.'; /* From current dev-dir */ if (tmp_file[-1] != FN_LIBCHAR) *tmp_file++ =FN_LIBCHAR; tmp_file[0]='*'; /* Windows needs this !??? */ tmp_file[1]='.'; tmp_file[2]='*'; tmp_file[3]='\0'; if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + sizeof(MEM_ROOT), MyFlags))) goto error; dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), ENTRIES_START_SIZE, ENTRIES_INCREMENT)) { my_free(buffer); goto error; } init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); /* MY_DIR structure is allocated and completly initialized at this point */ result= (MY_DIR*)buffer; #ifdef __BORLANDC__ if ((handle= findfirst(tmp_path,&find,0)) == -1L) #else if ((handle=_findfirst(tmp_path,&find)) == -1L) #endif { DBUG_PRINT("info", ("findfirst returned error, errno: %d", errno)); if (errno != EINVAL) goto error; /* Could not read the directory, no read access. Probably because by "chmod -r". continue and return zero files in dir */ } else { do { #ifdef __BORLANDC__ attrib= find.ff_attrib; #else attrib= find.attrib; /* Do not show hidden and system files which Windows sometimes create. Note. Because Borland's findfirst() is called with the third argument = 0 hidden/system files are excluded from the search. */ if (attrib & (_A_HIDDEN | _A_SYSTEM)) continue; #endif #ifdef __BORLANDC__ if (!(finfo.name= strdup_root(names_storage, find.ff_name))) goto error; #else if (!(finfo.name= strdup_root(names_storage, find.name))) goto error; #endif if (MyFlags & MY_WANT_STAT) { if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, sizeof(MY_STAT)))) goto error; memset(finfo.mystat, 0, sizeof(MY_STAT)); #ifdef __BORLANDC__ finfo.mystat->st_size=find.ff_fsize; #else finfo.mystat->st_size=find.size; #endif mode= MY_S_IREAD; if (!(attrib & _A_RDONLY)) mode|= MY_S_IWRITE; if (attrib & _A_SUBDIR) mode|= MY_S_IFDIR; finfo.mystat->st_mode= mode; #ifdef __BORLANDC__ finfo.mystat->st_mtime= ((uint32) find.ff_ftime); #else finfo.mystat->st_mtime= ((uint32) find.time_write); #endif } else finfo.mystat= NULL; if (push_dynamic(dir_entries_storage, (uchar*)&finfo)) goto error; } #ifdef __BORLANDC__ while (findnext(&find) == 0); #else while (_findnext(handle,&find) == 0); _findclose(handle); #endif } result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; result->number_off_files= dir_entries_storage->elements; if (!(MyFlags & MY_DONT_SORT)) my_qsort((void *) result->dir_entry, result->number_off_files, sizeof(FILEINFO), (qsort_cmp) comp_names); DBUG_PRINT("exit", ("found %d files", result->number_off_files)); DBUG_RETURN(result); error: my_errno=errno; #ifndef __BORLANDC__ if (handle != -1) _findclose(handle); #endif my_dirend(result); if (MyFlags & MY_FAE+MY_WME) { char errbuf[MYSYS_STRERROR_SIZE]; my_error(EE_DIR, MYF(ME_BELL+ME_WAITTANG), path, errno, my_strerror(errbuf, sizeof(errbuf), errno)); } DBUG_RETURN((MY_DIR *) NULL); } /* my_dir */
ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key) { /*register*/ ulong nr=1, nr2=4; HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { uchar *pos=(uchar*) key; key+=seg->length; if (seg->null_bit) { key++; /* Skip null byte */ if (*pos) /* Found null */ { nr^= (nr << 1) | 1; /* Add key pack length (2) to key for VARCHAR segments */ if (seg->type == HA_KEYTYPE_VARTEXT1) key+= 2; continue; } pos++; } if (seg->type == HA_KEYTYPE_TEXT) { const CHARSET_INFO *cs= seg->charset; uint length= seg->length; if (cs->mbmaxlen > 1) { uint char_length; char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen); set_if_smaller(length, char_length); } cs->coll->hash_sort(cs, pos, length, &nr, &nr2); } else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ { const CHARSET_INFO *cs= seg->charset; uint pack_length= 2; /* Key packing is constant */ uint length= uint2korr(pos); if (cs->mbmaxlen > 1) { uint char_length; char_length= my_charpos(cs, pos +pack_length, pos +pack_length + length, seg->length/cs->mbmaxlen); set_if_smaller(length, char_length); } cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2); key+= pack_length; } else { for (; pos < (uchar*) key ; pos++) { nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8); nr2+=3; } } } DBUG_PRINT("exit", ("hash: 0x%lx", nr)); return((ulong) nr); }
uchar *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key, uint nextflag) { reg1 HASH_INFO *pos,*prev_ptr; int flag; uint old_nextflag; HP_SHARE *share=info->s; DBUG_ENTER("hp_search"); old_nextflag=nextflag; flag=1; prev_ptr=0; if (share->records) { pos=hp_find_hash(&keyinfo->block, hp_mask(hp_hashnr(keyinfo, key), share->blength, share->records)); do { if (!hp_key_cmp(keyinfo, pos->ptr_to_rec, key)) { switch (nextflag) { case 0: /* Search after key */ DBUG_PRINT("exit", ("found key at 0x%lx", (long) pos->ptr_to_rec)); info->current_hash_ptr=pos; DBUG_RETURN(info->current_ptr= pos->ptr_to_rec); case 1: /* Search next */ if (pos->ptr_to_rec == info->current_ptr) nextflag=0; break; case 2: /* Search previous */ if (pos->ptr_to_rec == info->current_ptr) { my_errno=HA_ERR_KEY_NOT_FOUND; /* If gpos == 0 */ info->current_hash_ptr=prev_ptr; DBUG_RETURN(info->current_ptr=prev_ptr ? prev_ptr->ptr_to_rec : 0); } prev_ptr=pos; /* Prev. record found */ break; case 3: /* Search same */ if (pos->ptr_to_rec == info->current_ptr) { info->current_hash_ptr=pos; DBUG_RETURN(info->current_ptr); } } } if (flag) { flag=0; /* Reset flag */ if (hp_find_hash(&keyinfo->block, hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec), share->blength, share->records)) != pos) break; /* Wrong link */ } } while ((pos=pos->next_key)); } my_errno=HA_ERR_KEY_NOT_FOUND; if (nextflag == 2 && ! info->current_ptr) { /* Do a previous from end */ info->current_hash_ptr=prev_ptr; DBUG_RETURN(info->current_ptr=prev_ptr ? prev_ptr->ptr_to_rec : 0); } if (old_nextflag && nextflag) my_errno=HA_ERR_RECORD_CHANGED; /* Didn't find old record */ DBUG_PRINT("exit",("Error: %d",my_errno)); info->current_hash_ptr=0; DBUG_RETURN((info->current_ptr= 0)); }
/* Delete file. The function also makes best effort to minimize number of errors, where another program (or thread in the current program) has the the same file open. We're using 2 tricks to prevent the errors. 1. A usual Win32's DeleteFile() can with ERROR_SHARED_VIOLATION, because the file is opened in another application (often, antivirus or backup) We avoid the error by using CreateFile() with FILE_FLAG_DELETE_ON_CLOSE, instead of DeleteFile() 2. If file which is deleted (delete on close) but has not entirely gone, because it is still opened by some app, an attempt to trcreate file with the same name would result in yet another error. The workaround here is renaming a file to unique name. Symbolic link are deleted without renaming. Directories are not deleted. */ static int my_win_unlink(const char *name) { HANDLE handle= INVALID_HANDLE_VALUE; DWORD attributes; DWORD last_error; char unique_filename[MAX_PATH + 35]; unsigned long long tsc; /* time stamp counter, for unique filename*/ DBUG_ENTER("my_win_unlink"); attributes= GetFileAttributes(name); if (attributes == INVALID_FILE_ATTRIBUTES) { last_error= GetLastError(); DBUG_PRINT("error",("GetFileAttributes(%s) failed with %u\n", name, last_error)); goto error; } if (attributes & FILE_ATTRIBUTE_DIRECTORY) { DBUG_PRINT("error",("can't remove %s - it is a directory\n", name)); errno= EINVAL; DBUG_RETURN(-1); } if (attributes & FILE_ATTRIBUTE_REPARSE_POINT) { /* Symbolic link. Delete link, the not target */ if (!DeleteFile(name)) { last_error= GetLastError(); DBUG_PRINT("error",("DeleteFile(%s) failed with %u\n", name,last_error)); goto error; } DBUG_RETURN(0); } handle= CreateFile(name, DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL); if (handle != INVALID_HANDLE_VALUE) { /* We opened file without sharing flags (exclusive), no one else has this file opened, thus it is save to close handle to remove it. No renaming is necessary. */ CloseHandle(handle); DBUG_RETURN(0); } /* Can't open file exclusively, hence the file must be already opened by someone else. Open it for delete (with all FILE_SHARE flags set), rename to unique name, close. */ handle= CreateFile(name, DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL); if (handle == INVALID_HANDLE_VALUE) { last_error= GetLastError(); DBUG_PRINT("error", ("CreateFile(%s) with FILE_FLAG_DELETE_ON_CLOSE failed with %u\n", name,last_error)); goto error; } tsc= __rdtsc(); my_snprintf(unique_filename,sizeof(unique_filename),"%s.%llx.deleted", name, tsc); if (!MoveFile(name, unique_filename)) { DBUG_PRINT("warning", ("moving %s to unique filename failed, error %u\n", name,GetLastError())); } CloseHandle(handle); DBUG_RETURN(0); error: my_osmaperr(last_error); DBUG_RETURN(-1); }
int myrg_rrnd(MYRG_INFO *info,uchar *buf,ulonglong filepos) { int error; MI_INFO *isam_info; DBUG_ENTER("myrg_rrnd"); DBUG_PRINT("info",("offset: %lu", (ulong) filepos)); if (filepos == HA_OFFSET_ERROR) { if (!info->current_table) { if (info->open_tables == info->end_table) { /* No tables */ DBUG_RETURN(my_errno=HA_ERR_END_OF_FILE); } isam_info=(info->current_table=info->open_tables)->table; if (info->cache_in_use) mi_extra(isam_info,HA_EXTRA_CACHE,(uchar*) &info->cache_size); filepos=isam_info->s->pack.header_length; isam_info->lastinx= (uint) -1; /* Can't forward or backward */ } else { isam_info=info->current_table->table; filepos= isam_info->nextpos; } for (;;) { isam_info->update&= HA_STATE_CHANGED; if ((error=(*isam_info->s->read_rnd)(isam_info,(uchar*) buf, (my_off_t) filepos,1)) != HA_ERR_END_OF_FILE) DBUG_RETURN(error); if (info->cache_in_use) mi_extra(info->current_table->table, HA_EXTRA_NO_CACHE, (uchar*) &info->cache_size); if (info->current_table+1 == info->end_table) DBUG_RETURN(HA_ERR_END_OF_FILE); info->current_table++; info->last_used_table=info->current_table; if (info->cache_in_use) mi_extra(info->current_table->table, HA_EXTRA_CACHE, (uchar*) &info->cache_size); info->current_table->file_offset= info->current_table[-1].file_offset+ info->current_table[-1].table->state->data_file_length; isam_info=info->current_table->table; filepos=isam_info->s->pack.header_length; isam_info->lastinx= (uint) -1; } } info->current_table=find_table(info->open_tables, info->end_table-1,filepos); isam_info=info->current_table->table; isam_info->update&= HA_STATE_CHANGED; DBUG_RETURN((*isam_info->s->read_rnd) (isam_info, (uchar*) buf, (my_off_t) (filepos - info->current_table->file_offset), 0)); }
bool SCI_Transporter::doSend() { #ifdef DEBUG_TRANSPORTER NDB_TICKS startSec=0, stopSec=0; Uint32 startMicro=0, stopMicro=0, totalMicro=0; #endif sci_error_t err; Uint32 retry=0; if (!fetch_send_iovec_data()) return false; Uint32 used = m_send_iovec_used; if (used == 0) return true; // Nothing to send #ifdef DEBUG_TRANSPORTER Uint32 sizeToSend = 0; for (Uint32 i = 0; i < used; i++) sizeToSend += m_send_iovec[i].iov_len; if(sizeToSend < 1024 ) i1024++; if(sizeToSend > 1024 && sizeToSend < 2048 ) i10242048++; if(sizeToSend==2048) i2048++; if(sizeToSend>2048 && sizeToSend < 4096) i20484096++; if(sizeToSend==4096) i4096++; if(sizeToSend==4097) i4097++; #endif bool status = true; Uint32 curr = 0; Uint32 total = 0; while (curr < used) { tryagain: if (retry > 3) { DBUG_PRINT("error", ("SCI Transfer failed")); report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); status = false; break; } Uint32 segSize = m_send_iovec[curr].iov_len; Uint32 * insertPtr = (Uint32 *) (m_TargetSegm[m_ActiveAdapterId].writer)->getWritePtr(segSize); if(insertPtr != 0) { const Uint32 remoteOffset=(Uint32) ((char*)insertPtr - (char*)(m_TargetSegm[m_ActiveAdapterId].mappedMemory)); SCIMemCpy(m_TargetSegm[m_ActiveAdapterId].sequence, (void*)m_send_iovec[curr].iov_base, m_TargetSegm[m_ActiveAdapterId].rhm[m_ActiveAdapterId].map, remoteOffset, segSize, SCI_FLAG_ERROR_CHECK, &err); if (err != SCI_ERR_OK) { if (err == SCI_ERR_OUT_OF_RANGE || err == SCI_ERR_SIZE_ALIGNMENT || err == SCI_ERR_OFFSET_ALIGNMENT) { DBUG_PRINT("error", ("Data transfer error = %d", err)); report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); status = false; break; } if(err == SCI_ERR_TRANSFER_FAILED) { if(getLinkStatus(m_ActiveAdapterId)) { retry++; goto tryagain; } if (m_adapters == 1) { DBUG_PRINT("error", ("SCI Transfer failed")); report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); status = false; break; } m_failCounter++; Uint32 temp=m_ActiveAdapterId; if (getLinkStatus(m_StandbyAdapterId)) { failoverShmWriter(); SCIStoreBarrier(m_TargetSegm[m_StandbyAdapterId].sequence,0); m_ActiveAdapterId=m_StandbyAdapterId; m_StandbyAdapterId=temp; DBUG_PRINT("error", ("Swapping from adapter %u to %u", m_StandbyAdapterId, m_ActiveAdapterId)); } else { report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); DBUG_PRINT("error", ("SCI Transfer failed")); } } break; } else { SHM_Writer * writer = (m_TargetSegm[m_ActiveAdapterId].writer); writer->updateWritePtr(segSize); curr++; total += segSize; } } else { /** * If we end up here, the SCI segment is full. As long as we manage to * send _something_, that is ok. */ if (curr == 0) { DBUG_PRINT("error", ("the segment is full for some reason")); status = false; } break; } //if } if (total > 0) iovec_data_sent(total); return status; } // doSend()
void SCI_Transporter::setupRemoteSegment() { DBUG_ENTER("SCI_Transporter::setupRemoteSegment"); Uint32 sharedSize = 0; sharedSize =4096; //start of the buffer is page aligned Uint32 sizeOfBuffer = m_BufferSize; const Uint32 slack = MAX_MESSAGE_SIZE; sizeOfBuffer -= sharedSize; Uint32 *segPtr = (Uint32*) m_TargetSegm[m_ActiveAdapterId].mappedMemory ; Uint32 * remoteReadIndex = (Uint32*)segPtr; Uint32 * remoteWriteIndex = (Uint32*)(segPtr + 1); m_remoteStatusFlag = (Uint32*)(segPtr + 3); char * remoteStartOfBuf = ( char*)((char*)segPtr+(sharedSize)); writer = new SHM_Writer(remoteStartOfBuf, sizeOfBuffer, slack, remoteReadIndex, remoteWriteIndex); writer->clear(); m_TargetSegm[0].writer=writer; if(createSequence(m_ActiveAdapterId)!=SCI_ERR_OK) { report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE); DBUG_PRINT("error", ("Unable to create sequence on active")); doDisconnect(); } if (m_adapters > 1) { segPtr = (Uint32*) m_TargetSegm[m_StandbyAdapterId].mappedMemory ; Uint32 * remoteReadIndex2 = (Uint32*)segPtr; Uint32 * remoteWriteIndex2 = (Uint32*) (segPtr + 1); m_remoteStatusFlag2 = (Uint32*)(segPtr + 3); char * remoteStartOfBuf2 = ( char*)((char *)segPtr+sharedSize); /** * setup a writer. writer2 is used to mirror the changes of * writer on the standby * segment, so that in the case of a failover, we can switch * to the stdby seg. quickly.* */ writer2 = new SHM_Writer(remoteStartOfBuf2, sizeOfBuffer, slack, remoteReadIndex2, remoteWriteIndex2); * remoteReadIndex = 0; * remoteWriteIndex = 0; writer2->clear(); m_TargetSegm[1].writer=writer2; if(createSequence(m_StandbyAdapterId)!=SCI_ERR_OK) { report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE); DBUG_PRINT("error", ("Unable to create sequence on standby")); doDisconnect(); } } DBUG_VOID_RETURN; } //setupRemoteSegment
sci_error_t SCI_Transporter::initLocalSegment() { DBUG_ENTER("SCI_Transporter::initLocalSegment"); Uint32 segmentSize = m_BufferSize; Uint32 offset = 0; sci_error_t err; if(!m_sciinit) { for(Uint32 i=0; i<m_adapters ; i++) { SCIOpen(&(sciAdapters[i].scidesc), FLAGS, &err); sciAdapters[i].localSciNodeId=getLocalNodeId(i); DBUG_PRINT("info", ("SCInode iD %d adapter %d\n", sciAdapters[i].localSciNodeId, i)); if(err != SCI_ERR_OK) { DBUG_PRINT("error", ("Cannot open an SCI virtual device. Error code 0x%x", err)); DBUG_RETURN(err); } } } m_sciinit=true; SCICreateSegment(sciAdapters[0].scidesc, &(m_SourceSegm[0].localHandle), hostSegmentId(localNodeId, remoteNodeId), segmentSize, 0, 0, 0, &err); if(err != SCI_ERR_OK) { DBUG_PRINT("error", ("Error creating segment, err = 0x%x", err)); DBUG_RETURN(err); } else { DBUG_PRINT("info", ("created segment id : %d", hostSegmentId(localNodeId, remoteNodeId))); } /** Prepare the segment*/ for(Uint32 i=0; i < m_adapters; i++) { SCIPrepareSegment((m_SourceSegm[0].localHandle), i, FLAGS, &err); if(err != SCI_ERR_OK) { DBUG_PRINT("error", ("Local Segment is not accessible by an SCI adapter. Error code 0x%x\n", err)); DBUG_RETURN(err); } } m_SourceSegm[0].mappedMemory = SCIMapLocalSegment((m_SourceSegm[0].localHandle), &(m_SourceSegm[0].lhm[0].map), offset, segmentSize, NULL, FLAGS, &err); if(err != SCI_ERR_OK) { DBUG_PRINT("error", ("Cannot map area of size %d. Error code 0x%x", segmentSize,err)); doDisconnect(); DBUG_RETURN(err); } /** Make the local segment available*/ for(Uint32 i=0; i < m_adapters; i++) { SCISetSegmentAvailable((m_SourceSegm[0].localHandle), i, FLAGS, &err); if(err != SCI_ERR_OK) { DBUG_PRINT("error", ("Local Segment is not available for remote connections. Error code 0x%x\n", err)); DBUG_RETURN(err); } } setupLocalSegment(); DBUG_RETURN(err); } // initLocalSegment()
int my_copy(const char *from, const char *to, myf MyFlags) { size_t Count; my_bool new_file_stat= 0; /* 1 if we could stat "to" */ int create_flag; File from_file,to_file; uchar buff[IO_SIZE]; MY_STAT stat_buff,new_stat_buff; DBUG_ENTER("my_copy"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); from_file=to_file= -1; DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */ if (MyFlags & MY_HOLD_ORIGINAL_MODES) /* Copy stat if possible */ new_file_stat= test(my_stat((char*) to, &new_stat_buff, MYF(0))); if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0) { if (!my_stat(from, &stat_buff, MyFlags)) { my_errno=errno; goto err; } if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat) stat_buff=new_stat_buff; create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC; if ((to_file= my_create(to,(int) stat_buff.st_mode, O_WRONLY | create_flag | O_BINARY | O_SHARE, MyFlags)) < 0) goto err; while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0) { if (Count == (uint) -1 || my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP))) goto err; } /* sync the destination file */ if (MyFlags & MY_SYNC) { if (my_sync(to_file, MyFlags)) goto err; } if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags)) DBUG_RETURN(-1); /* Error on close */ /* Copy modes if possible */ if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat) DBUG_RETURN(0); /* File copyed but not stat */ /* Copy modes */ if (chmod(to, stat_buff.st_mode & 07777)) { my_errno= errno; if (MyFlags & (MY_FAE+MY_WME)) my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno); goto err; } #if !defined(__WIN__) /* Copy ownership */ if (chown(to, stat_buff.st_uid, stat_buff.st_gid)) { my_errno= errno; if (MyFlags & (MY_FAE+MY_WME)) my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno); goto err; } #endif if (MyFlags & MY_COPYTIME) { struct utimbuf timep; timep.actime = stat_buff.st_atime; timep.modtime = stat_buff.st_mtime; (void) utime((char*) to, &timep); /* last accessed and modified times */ } DBUG_RETURN(0); } err: if (from_file >= 0) (void) my_close(from_file,MyFlags); if (to_file >= 0) { (void) my_close(to_file, MyFlags); /* attempt to delete the to-file we've partially written */ (void) my_delete(to, MyFlags); } DBUG_RETURN(-1); } /* my_copy */
File create_temp_file(char *to, const char *dir, const char *prefix, int mode, myf MyFlags) { File file= -1; #ifdef _WIN32 TCHAR path_buf[MAX_PATH-14]; #endif DBUG_ENTER("create_temp_file"); DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir, prefix)); #if defined(_WIN32) /* Use GetTempPath to determine path for temporary files. This is because the documentation for GetTempFileName has the following to say about this parameter: "If this parameter is NULL, the function fails." */ if (!dir) { if(GetTempPath(sizeof(path_buf), path_buf) > 0) dir = path_buf; } /* Use GetTempFileName to generate a unique filename, create the file and release it's handle - uses up to the first three letters from prefix */ if (GetTempFileName(dir, prefix, 0, to) == 0) DBUG_RETURN(-1); DBUG_PRINT("info", ("name: %s", to)); /* Open the file without the "open only if file doesn't already exist" since the file has already been created by GetTempFileName */ if ((file= my_open(to, (mode & ~O_EXCL), MyFlags)) < 0) { /* Open failed, remove the file created by GetTempFileName */ int tmp= my_errno(); (void) my_delete(to, MYF(0)); set_my_errno(tmp); } #else /* mkstemp() is available on all non-Windows supported platforms. */ { char prefix_buff[30]; uint pfx_len; File org_file; pfx_len= (uint) (my_stpcpy(my_stpnmov(prefix_buff, prefix ? prefix : "tmp.", sizeof(prefix_buff)-7),"XXXXXX") - prefix_buff); if (!dir && ! (dir =getenv("TMPDIR"))) dir= DEFAULT_TMPDIR; if (strlen(dir)+ pfx_len > FN_REFLEN-2) { errno=ENAMETOOLONG; set_my_errno(ENAMETOOLONG); DBUG_RETURN(file); } my_stpcpy(convert_dirname(to,dir,NullS),prefix_buff); org_file=mkstemp(to); if (mode & O_TEMPORARY) (void) my_delete(to, MYF(MY_WME)); file=my_register_filename(org_file, to, FILE_BY_MKSTEMP, EE_CANTCREATEFILE, MyFlags); /* If we didn't manage to register the name, remove the temp file */ if (org_file >= 0 && file < 0) { int tmp=my_errno(); close(org_file); (void) my_delete(to, MYF(MY_WME)); set_my_errno(tmp); } } #endif if (file >= 0) { mysql_mutex_lock(&THR_LOCK_open); my_tmp_file_created++; mysql_mutex_unlock(&THR_LOCK_open); } DBUG_RETURN(file); }
int nisam_update(register N_INFO *info, const byte *oldrec, const byte *newrec) { int flag,key_changed,save_errno; reg3 ulong pos; uint i,length; uchar old_key[N_MAX_KEY_BUFF],*new_key; DBUG_ENTER("nisam_update"); LINT_INIT(save_errno); if (!(info->update & HA_STATE_AKTIV)) { my_errno=HA_ERR_KEY_NOT_FOUND; DBUG_RETURN(-1); } if (info->s->base.options & HA_OPTION_READ_ONLY_DATA) { my_errno=EACCES; DBUG_RETURN(-1); } pos=info->lastpos; #ifndef NO_LOCKING if (_nisam_readinfo(info,F_WRLCK,1)) DBUG_RETURN(-1); #endif if ((*info->s->compare_record)(info,oldrec)) { save_errno=my_errno; goto err_end; /* Record has changed */ } if (info->s->state.key_file_length >= info->s->base.max_key_file_length - info->s->blocksize* INDEX_BLOCK_MARGIN *info->s->state.keys) { save_errno=HA_ERR_INDEX_FILE_FULL; goto err_end; } /* Flyttar de element i isamfilen som m}ste flyttas */ new_key=info->lastkey+info->s->base.max_key_length; key_changed=HA_STATE_KEY_CHANGED; /* We changed current database */ /* Remove key that didn't change */ for (i=0 ; i < info->s->state.keys ; i++) { length=_nisam_make_key(info,i,new_key,newrec,pos); if (length != _nisam_make_key(info,i,old_key,oldrec,pos) || memcmp((byte*) old_key,(byte*) new_key,length)) { if ((int) i == info->lastinx) key_changed|=HA_STATE_WRITTEN; /* Mark that keyfile changed */ if (_nisam_ck_delete(info,i,old_key)) goto err; if (_nisam_ck_write(info,i,new_key)) goto err; } } if ((*info->s->update_record)(info,pos,newrec)) goto err; info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV | key_changed); nisam_log_record(LOG_UPDATE,info,newrec,info->lastpos,0); VOID(_nisam_writeinfo(info,test(key_changed))); allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(0); err: DBUG_PRINT("error",("key: %d errno: %d",i,my_errno)); save_errno=my_errno; if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL) { info->errkey= (int) i; flag=0; do { length=_nisam_make_key(info,i,new_key,newrec,pos); if (length != _nisam_make_key(info,i,old_key,oldrec,pos) || memcmp((byte*) old_key,(byte*) new_key,length)) { if ((flag++ && _nisam_ck_delete(info,i,new_key)) || _nisam_ck_write(info,i,old_key)) break; } } while (i-- != 0); } info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV | key_changed); err_end: nisam_log_record(LOG_UPDATE,info,newrec,info->lastpos,save_errno); VOID(_nisam_writeinfo(info,1)); allow_break(); /* Allow SIGHUP & SIGINT */ my_errno=(save_errno == HA_ERR_KEY_NOT_FOUND) ? HA_ERR_CRASHED : save_errno; DBUG_RETURN(-1); } /* nisam_update */
void my_end(int infoflag) { /* this code is suboptimal to workaround a bug in Sun CC: Sun C++ 5.6 2004/06/02 for x86, and should not be optimized until this compiler is not in use anymore */ FILE *info_file= DBUG_FILE; my_bool print_info= (info_file != stderr); DBUG_ENTER("my_end"); if (!info_file) { info_file= stderr; print_info= 0; } DBUG_PRINT("info",("Shutting down: print_info: %d", print_info)); if ((infoflag & MY_CHECK_ERROR) || print_info) { /* Test if some file is left open */ if (my_file_opened | my_stream_opened) { sprintf(errbuff[0],EE(EE_OPEN_WARNING),my_file_opened,my_stream_opened); (void) my_message_no_curses(EE_OPEN_WARNING,errbuff[0],ME_BELL); DBUG_PRINT("error",("%s",errbuff[0])); } } free_charsets(); my_once_free(); if ((infoflag & MY_GIVE_INFO) || print_info) { #ifdef HAVE_GETRUSAGE struct rusage rus; #ifdef HAVE_purify /* Purify assumes that rus is uninitialized after getrusage call */ bzero((char*) &rus, sizeof(rus)); #endif if (!getrusage(RUSAGE_SELF, &rus)) fprintf(info_file,"\n\ User time %.2f, System time %.2f\n\ Maximum resident set size %ld, Integral resident set size %ld\n\ Non-physical pagefaults %ld, Physical pagefaults %ld, Swaps %ld\n\ Blocks in %ld out %ld, Messages in %ld out %ld, Signals %ld\n\ Voluntary context switches %ld, Involuntary context switches %ld\n", (rus.ru_utime.tv_sec * SCALE_SEC + rus.ru_utime.tv_usec / SCALE_USEC) / 100.0, (rus.ru_stime.tv_sec * SCALE_SEC + rus.ru_stime.tv_usec / SCALE_USEC) / 100.0, rus.ru_maxrss, rus.ru_idrss, rus.ru_minflt, rus.ru_majflt, rus.ru_nswap, rus.ru_inblock, rus.ru_oublock, rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals, rus.ru_nvcsw, rus.ru_nivcsw); #endif #if ( defined(MSDOS) || defined(__NETWARE__) ) && !defined(__WIN__) fprintf(info_file,"\nRun time: %.1f\n",(double) clock()/CLOCKS_PER_SEC); #endif #if defined(SAFEMALLOC) TERMINATE(stderr); /* Give statistic on screen */ #elif defined(__WIN__) && defined(_MSC_VER) _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR ); _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR ); _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR ); _CrtCheckMemory(); _CrtDumpMemoryLeaks(); #endif } #ifdef THREAD DBUG_POP(); /* Must be done before my_thread_end */ my_thread_end(); my_thread_global_end(); #if defined(SAFE_MUTEX) /* Check on destroying of mutexes. A few may be left that will get cleaned up by C++ destructors */ safe_mutex_end(infoflag & MY_GIVE_INFO ? stderr : (FILE *) 0); #endif /* defined(SAFE_MUTEX) */ #endif /* THREAD */ #ifdef __WIN__ if (have_tcpip) WSACleanup(); #endif /* __WIN__ */ my_init_done=0; } /* my_end */
int mi_rnext(MI_INFO *info, byte *buf, int inx) { int error,changed; uint flag; DBUG_ENTER("mi_rnext"); if ((inx = _mi_check_index(info,inx)) < 0) DBUG_RETURN(my_errno); flag=SEARCH_BIGGER; /* Read next */ if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_PREV_FOUND) flag=0; /* Read first */ if (fast_mi_readinfo(info)) DBUG_RETURN(my_errno); if (info->s->concurrent_insert) rw_rdlock(&info->s->key_root_lock[inx]); changed=_mi_test_if_changed(info); if (!flag) { switch(info->s->keyinfo[inx].key_alg){ #ifdef HAVE_RTREE_KEYS case HA_KEY_ALG_RTREE: error=rtree_get_first(info,inx,info->lastkey_length); break; #endif case HA_KEY_ALG_BTREE: default: error=_mi_search_first(info,info->s->keyinfo+inx, info->s->state.key_root[inx]); break; } } else { switch (info->s->keyinfo[inx].key_alg) { #ifdef HAVE_RTREE_KEYS case HA_KEY_ALG_RTREE: /* Note that rtree doesn't support that the table may be changed since last call, so we do need to skip rows inserted by other threads like in btree */ error= rtree_get_next(info,inx,info->lastkey_length); break; #endif case HA_KEY_ALG_BTREE: default: if (!changed) error= _mi_search_next(info,info->s->keyinfo+inx,info->lastkey, info->lastkey_length,flag, info->s->state.key_root[inx]); else error= _mi_search(info,info->s->keyinfo+inx,info->lastkey, USE_WHOLE_KEY,flag, info->s->state.key_root[inx]); } } if (info->s->concurrent_insert) { if (!error) { while (info->lastpos >= info->state->data_file_length) { /* Skip rows inserted by other threads since we got a lock */ if ((error=_mi_search_next(info,info->s->keyinfo+inx, info->lastkey, info->lastkey_length, SEARCH_BIGGER, info->s->state.key_root[inx]))) break; } } rw_unlock(&info->s->key_root_lock[inx]); } /* Don't clear if database-changed */ info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update|= HA_STATE_NEXT_FOUND; if (error) { if (my_errno == HA_ERR_KEY_NOT_FOUND) my_errno=HA_ERR_END_OF_FILE; } else if (!buf) { DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0); } else if (!(*info->read_record)(info,info->lastpos,buf)) { info->update|= HA_STATE_AKTIV; /* Record is read */ DBUG_RETURN(0); } DBUG_PRINT("error",("Got error: %d, errno: %d",error, my_errno)); DBUG_RETURN(my_errno); } /* mi_rnext */
int main(int argc, char *argv[]) { register uint i,j; uint ant,n1,n2,n3; uint write_count,update,opt_delete,check2,dupp_keys,found_key; int error; ulong pos; unsigned long key_check; uchar record[128],record2[128],record3[128],key[10]; const char *filename,*filename2; HP_INFO *file,*file2; HP_SHARE *tmp_share; HP_KEYDEF keyinfo[MAX_KEYS]; HA_KEYSEG keyseg[MAX_KEYS*5]; HEAP_PTR UNINIT_VAR(position); HP_CREATE_INFO hp_create_info; CHARSET_INFO *cs= &my_charset_latin1; my_bool unused; MY_INIT(argv[0]); /* init my_sys library & pthreads */ filename= "test2"; filename2= "test2_2"; file=file2=0; get_options(argc,argv); bzero(&hp_create_info, sizeof(hp_create_info)); hp_create_info.max_table_size= 2*1024L*1024L; hp_create_info.keys= keys; hp_create_info.keydef= keyinfo; hp_create_info.reclength= reclength; hp_create_info.max_records= (ulong) flag*100000L; hp_create_info.min_records= (ulong) recant/2; write_count=update=opt_delete=0; key_check=0; keyinfo[0].seg=keyseg; keyinfo[0].keysegs=1; keyinfo[0].flag= 0; keyinfo[0].algorithm= HA_KEY_ALG_HASH; keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY; keyinfo[0].seg[0].start=0; keyinfo[0].seg[0].length=6; keyinfo[0].seg[0].null_bit=0; keyinfo[0].seg[0].charset=cs; keyinfo[1].seg=keyseg+1; keyinfo[1].keysegs=2; keyinfo[1].flag=0; keyinfo[1].algorithm= HA_KEY_ALG_HASH; keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY; keyinfo[1].seg[0].start=7; keyinfo[1].seg[0].length=6; keyinfo[1].seg[0].null_bit=0; keyinfo[1].seg[0].charset=cs; keyinfo[1].seg[1].type=HA_KEYTYPE_TEXT; keyinfo[1].seg[1].start=0; /* key in two parts */ keyinfo[1].seg[1].length=6; keyinfo[1].seg[1].null_bit=0; keyinfo[1].seg[1].charset=cs; keyinfo[2].seg=keyseg+3; keyinfo[2].keysegs=1; keyinfo[2].flag=HA_NOSAME; keyinfo[2].algorithm= HA_KEY_ALG_HASH; keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY; keyinfo[2].seg[0].start=12; keyinfo[2].seg[0].length=8; keyinfo[2].seg[0].null_bit=0; keyinfo[2].seg[0].charset=cs; keyinfo[3].seg=keyseg+4; keyinfo[3].keysegs=1; keyinfo[3].flag=HA_NOSAME; keyinfo[3].algorithm= HA_KEY_ALG_HASH; keyinfo[3].seg[0].type=HA_KEYTYPE_BINARY; keyinfo[3].seg[0].start=37; keyinfo[3].seg[0].length=1; keyinfo[3].seg[0].null_bit=1; keyinfo[3].seg[0].null_pos=38; keyinfo[3].seg[0].charset=cs; bzero((char*) key1,sizeof(key1)); bzero((char*) key3,sizeof(key3)); printf("- Creating heap-file\n"); if (heap_create(filename, &hp_create_info, &tmp_share, &unused) || !(file= heap_open(filename, 2))) goto err; signal(SIGINT,endprog); printf("- Writing records:s\n"); strmov((char*) record," ..... key"); for (i=0 ; i < recant ; i++) { n1=rnd(1000); n2=rnd(100); n3=rnd(MY_MIN(recant*5,MAX_RECORDS)); make_record(record,n1,n2,n3,"Pos",write_count); if (heap_write(file,record)) { if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0) { printf("Error: %d in write at record: %d\n",my_errno,i); goto err; } if (verbose) printf(" Double key: %d\n",n3); } else { if (key3[n3] == 1) { printf("Error: Didn't get error when writing second key: '%8d'\n",n3); goto err; } write_count++; key1[n1]++; key3[n3]=1; key_check+=n1; } if (testflag == 1 && heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } } if (testflag == 1) goto end; if (heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } printf("- Delete\n"); for (i=0 ; i < write_count/10 ; i++) { for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; if (j != 0) { sprintf((char*) key,"%6d",j); if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT)) { printf("can't find key1: \"%s\"\n",(char*) key); goto err; } if (heap_delete(file,record)) { printf("error: %d; can't delete record: \"%s\"\n", my_errno,(char*) record); goto err; } opt_delete++; key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; key_check-=atoi((char*) record); if (testflag == 2 && heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } } else puts("Warning: Skipping delete test because no dupplicate keys"); } if (testflag==2) goto end; if (heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } printf("- Update\n"); for (i=0 ; i < write_count/10 ; i++) { n1=rnd(1000); n2=rnd(100); n3=rnd(MY_MIN(recant*2,MAX_RECORDS)); make_record(record2, n1, n2, n3, "XXX", update); if (rnd(2) == 1) { if (heap_scan_init(file)) goto err; j=rnd(write_count-opt_delete); while ((error=heap_scan(file,record) == HA_ERR_RECORD_DELETED) || (!error && j)) { if (!error) j--; } if (error) goto err; } else { for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; if (!key1[j]) continue; sprintf((char*) key,"%6d",j); if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT)) { printf("can't find key1: \"%s\"\n",(char*) key); goto err; } } if (heap_update(file,record,record2)) { if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0) { printf("error: %d; can't update:\nFrom: \"%s\"\nTo: \"%s\"\n", my_errno,(char*) record, (char*) record2); goto err; } if (verbose) printf("Double key when tried to update:\nFrom: \"%s\"\nTo: \"%s\"\n", (char*) record, (char*) record2); } else { key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; key1[n1]++; key3[n3]=1; update++; key_check=key_check-atoi((char*) record)+n1; } if (testflag == 3 && heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } } if (testflag == 3) goto end; if (heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } for (i=999, dupp_keys=found_key=0 ; i>0 ; i--) { if (key1[i] > dupp_keys) { dupp_keys=key1[i]; found_key=i; } sprintf((char*) key,"%6d",found_key); } if (dupp_keys > 3) { if (!silent) printf("- Read first key - next - delete - next -> last\n"); DBUG_PRINT("progpos",("first - next - delete - next -> last")); if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT)) goto err; if (heap_rnext(file,record3)) goto err; if (heap_delete(file,record3)) goto err; key_check-=atoi((char*) record3); key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; opt_delete++; ant=2; while ((error=heap_rnext(file,record3)) == 0 || error == HA_ERR_RECORD_DELETED) if (! error) ant++; if (ant != dupp_keys) { printf("next: I can only find: %d records of %d\n", ant,dupp_keys); goto end; } dupp_keys--; if (heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } if (!silent) printf("- Read last key - delete - prev - prev - opt_delete - prev -> first\n"); if (heap_rprev(file,record)) goto err; if (heap_delete(file,record3)) goto err; key_check-=atoi((char*) record3); key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; opt_delete++; if (heap_rprev(file,record3) || heap_rprev(file,record3)) goto err; if (heap_delete(file,record3)) goto err; key_check-=atoi((char*) record3); key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; opt_delete++; ant=3; while ((error=heap_rprev(file,record3)) == 0 || error == HA_ERR_RECORD_DELETED) { if (! error) ant++; } if (ant != dupp_keys) { printf("next: I can only find: %d records of %d\n", ant,dupp_keys); goto end; } dupp_keys-=2; if (heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } } else puts("Warning: Not enough duplicated keys: Skipping delete key check"); if (!silent) printf("- Read (first) - next - delete - next -> last\n"); DBUG_PRINT("progpos",("first - next - delete - next -> last")); if (heap_scan_init(file)) goto err; while ((error=heap_scan(file,record3) == HA_ERR_RECORD_DELETED)) ; if (error) goto err; if (heap_delete(file,record3)) goto err; key_check-=atoi((char*) record3); opt_delete++; key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; ant=0; while ((error=heap_scan(file,record3)) == 0 || error == HA_ERR_RECORD_DELETED) if (! error) ant++; if (ant != write_count-opt_delete) { printf("next: Found: %d records of %d\n",ant,write_count-opt_delete); goto end; } if (heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } puts("- Test if: Read rrnd - same - rkey - same"); DBUG_PRINT("progpos",("Read rrnd - same")); pos=rnd(write_count-opt_delete-5)+5; heap_scan_init(file); i=5; while ((error=heap_scan(file,record)) == HA_ERR_RECORD_DELETED || (error == 0 && pos)) { if (!error) pos--; if (i-- == 0) { bmove(record3,record,reclength); position=heap_position(file); } } if (error) goto err; bmove(record2,record,reclength); if (heap_rsame(file,record,-1) || heap_rsame(file,record2,2)) goto err; if (memcmp(record2,record,reclength)) { puts("heap_rsame didn't find right record"); goto end; } puts("- Test of read through position"); if (heap_rrnd(file,record,position)) goto err; if (memcmp(record3,record,reclength)) { puts("heap_frnd didn't find right record"); goto end; } printf("- heap_info\n"); { HEAPINFO info; heap_info(file,&info,0); /* We have to test with opt_delete +1 as this may be the case if the last inserted row was a duplicate key */ if (info.records != write_count-opt_delete || (info.deleted != opt_delete && info.deleted != opt_delete+1)) { puts("Wrong info from heap_info"); printf("Got: records: %ld(%d) deleted: %ld(%d)\n", info.records,write_count-opt_delete,info.deleted,opt_delete); } } printf("- Read through all records with scan\n"); if (heap_reset(file) || heap_extra(file,HA_EXTRA_CACHE)) { puts("got error from heap_extra"); goto end; } ant=check2=0; heap_scan_init(file); while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE && ant < write_count + 10) { if (!error) { ant++; check2+=calc_check(record,reclength); } } if (ant != write_count-opt_delete) { printf("scan: I can only find: %d records of %d\n", ant, write_count-opt_delete); goto end; } if (heap_extra(file,HA_EXTRA_NO_CACHE)) { puts("got error from heap_extra(HA_EXTRA_NO_CACHE)"); goto end; } for (i=999, dupp_keys=found_key=0 ; i>0 ; i--) { if (key1[i] > dupp_keys) { dupp_keys=key1[i]; found_key=i; } sprintf((char*) key,"%6d",found_key); } printf("- Read through all keys with first-next-last-prev\n"); ant=0; for (error=heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT); ! error ; error=heap_rnext(file,record)) ant++; if (ant != dupp_keys) { printf("first-next: I can only find: %d records of %d\n", ant, dupp_keys); goto end; } ant=0; for (error=heap_rprev(file,record) ; ! error ; error=heap_rprev(file,record)) { ant++; check2+=calc_check(record,reclength); } if (ant != dupp_keys) { printf("last-prev: I can only find: %d records of %d\n", ant, dupp_keys); goto end; } if (testflag == 4) goto end; printf("- Reading through all rows through keys\n"); if (!(file2=heap_open(filename, 2))) goto err; if (heap_scan_init(file)) goto err; while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE) { if (error == 0) { if (heap_rkey(file2,record2,2,record+keyinfo[2].seg[0].start,8, HA_READ_KEY_EXACT)) { printf("can't find key3: \"%.8s\"\n", record+keyinfo[2].seg[0].start); goto err; } } } heap_close(file2); printf("- Creating output heap-file 2\n"); hp_create_info.keys= 1; hp_create_info.max_records= 0; hp_create_info.min_records= 0; if (heap_create(filename2, &hp_create_info, &tmp_share, &unused) || !(file2= heap_open_from_share_and_register(tmp_share, 2))) goto err; printf("- Copying and removing records\n"); if (heap_scan_init(file)) goto err; while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE) { if (error == 0) { if (heap_write(file2,record)) goto err; key_check-=atoi((char*) record); write_count++; if (heap_delete(file,record)) goto err; opt_delete++; } pos++; } printf("- Checking heap tables\n"); if (heap_check_heap(file,1) || heap_check_heap(file2,1)) { puts("Heap keys crashed"); goto err; } if (my_errno != HA_ERR_END_OF_FILE) printf("error: %d from heap_rrnd\n",my_errno); if (key_check) printf("error: Some read got wrong: check is %ld\n",(long) key_check); end: printf("\nFollowing test have been made:\n"); printf("Write records: %d\nUpdate records: %d\nDelete records: %d\n", write_count,update,opt_delete); heap_clear(file); if (heap_close(file) || (file2 && heap_close(file2))) goto err; heap_delete_table(filename2); hp_panic(HA_PANIC_CLOSE); my_end(MY_GIVE_INFO); return(0); err: printf("Got error: %d when using heap-database\n",my_errno); (void) heap_close(file); return(1); } /* main */
ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec) { ulong nr=1, nr2=4; HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { uchar *pos=(uchar*) rec+seg->start,*end=pos+seg->length; if (seg->null_bit) { if (rec[seg->null_pos] & seg->null_bit) { nr^= (nr << 1) | 1; continue; } } if (seg->type == HA_KEYTYPE_TEXT) { const CHARSET_INFO *cs= seg->charset; uint char_length= seg->length; if (cs->mbmaxlen > 1) { char_length= my_charpos(cs, pos, pos + char_length, char_length / cs->mbmaxlen); set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ } cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2); } else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ { const CHARSET_INFO *cs= seg->charset; uint pack_length= seg->bit_start; uint length= hp_calc_blob_length(pack_length, pos); if (seg->flag & HA_BLOB_PART) { memcpy(&pos, pos + pack_length, sizeof(char *)); } else { pos+= pack_length; } if (cs->mbmaxlen > 1) { uint char_length; char_length= my_charpos(cs, pos, pos + length, seg->length/cs->mbmaxlen); set_if_smaller(length, char_length); } cs->coll->hash_sort(cs, pos, length, &nr, &nr2); } else { for (; pos < end ; pos++) { nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8); nr2+=3; } } } DBUG_PRINT("exit", ("hash: 0x%lx", nr)); return(nr); }
/* Change size of file. SYNOPSIS my_chsize() fd File descriptor new_length New file size filler If we don't have truncate, fill up all bytes after new_length with this character MyFlags Flags DESCRIPTION my_chsize() truncates file if shorter else fill with the filler character. The function also changes the file pointer. Usually it points to the end of the file after execution. RETURN VALUE 0 Ok 1 Error */ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) { my_off_t oldsize; uchar buff[IO_SIZE]; DBUG_ENTER("my_chsize"); DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength, MyFlags)); if ((oldsize= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength) DBUG_RETURN(0); DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize)); if (oldsize > newlength) { #ifdef _WIN32 if (my_win_chsize(fd, newlength)) { my_errno= errno; goto err; } DBUG_RETURN(0); #elif defined(HAVE_FTRUNCATE) if (ftruncate(fd, (off_t) newlength)) { my_errno= errno; goto err; } DBUG_RETURN(0); #elif defined(HAVE_CHSIZE) if (chsize(fd, (off_t) newlength)) { my_errno=errno; goto err; } DBUG_RETURN(0); #else /* Fill space between requested length and true length with 'filler' We should never come here on any modern machine */ if (my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE)) == MY_FILEPOS_ERROR) { goto err; } swap_variables(my_off_t, newlength, oldsize); #endif } /* Full file with 'filler' until it's as big as requested */ bfill(buff, IO_SIZE, filler); while (newlength-oldsize > IO_SIZE) { if (my_write(fd, buff, IO_SIZE, MYF(MY_NABP))) goto err; oldsize+= IO_SIZE; } if (my_write(fd,buff,(size_t) (newlength-oldsize), MYF(MY_NABP))) goto err; DBUG_RETURN(0); err: DBUG_PRINT("error", ("errno: %d", errno)); if (MyFlags & MY_WME) my_error(EE_CANT_CHSIZE, MYF(ME_BELL+ME_WAITTANG), my_errno); DBUG_RETURN(1); } /* my_chsize */
struct st_VioSSLConnectorFd * new_VioSSLConnectorFd(const char* key_file, const char* cert_file, const char* ca_file, const char* ca_path, const char* cipher) { int verify = SSL_VERIFY_NONE; struct st_VioSSLConnectorFd* ptr; int result; DH *dh=NULL; DBUG_ENTER("new_VioSSLConnectorFd"); DBUG_PRINT("enter", ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s", key_file, cert_file, ca_path, ca_file, cipher)); if (!(ptr=((struct st_VioSSLConnectorFd*) my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0))))) DBUG_RETURN(0); ptr->ssl_context= 0; ptr->ssl_method= 0; /* FIXME: constants! */ if (!ssl_algorithms_added) { DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()")); ssl_algorithms_added = TRUE; OpenSSL_add_all_algorithms(); } if (!ssl_error_strings_loaded) { DBUG_PRINT("info", ("todo:SSL_load_error_strings()")); ssl_error_strings_loaded = TRUE; SSL_load_error_strings(); } ptr->ssl_method = TLSv1_client_method(); ptr->ssl_context = SSL_CTX_new(ptr->ssl_method); DBUG_PRINT("info", ("ssl_context: %p",ptr->ssl_context)); if (ptr->ssl_context == 0) { DBUG_PRINT("error", ("SSL_CTX_new failed")); report_errors(); goto ctor_failure; } /* SSL_CTX_set_options SSL_CTX_set_info_callback */ if (cipher) { result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher); DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result)); } SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback); if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1) { DBUG_PRINT("error", ("vio_set_cert_stuff failed")); report_errors(); goto ctor_failure; } if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file,ca_path) == 0) { DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); if (SSL_CTX_set_default_verify_paths(ptr->ssl_context) == 0) { DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed")); report_errors(); goto ctor_failure; } } /* DH stuff */ dh=get_dh512(); SSL_CTX_set_tmp_dh(ptr->ssl_context,dh); DH_free(dh); DBUG_RETURN(ptr); ctor_failure: DBUG_PRINT("exit", ("there was an error")); my_free((gptr)ptr,MYF(0)); DBUG_RETURN(0); }
bool SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd) { DBUG_ENTER("SHM_Transporter::connect_client_impl"); SocketInputStream s_input(sockfd); SocketOutputStream s_output(sockfd); char buf[256]; // Wait for server to create and attach DBUG_PRINT("info", ("Wait for server to create and attach")); if (s_input.gets(buf, 256) == 0) { NDB_CLOSE_SOCKET(sockfd); DBUG_PRINT("error", ("Server id %d did not attach", remoteNodeId)); DBUG_RETURN(false); } if(sscanf(buf, "shm server 1 ok: %d", &m_remote_pid) != 1) { NDB_CLOSE_SOCKET(sockfd); DBUG_RETURN(false); } // Create if(!_shmSegCreated){ if (!ndb_shm_get()) { NDB_CLOSE_SOCKET(sockfd); DBUG_PRINT("error", ("Failed create of shm seg to node %d", remoteNodeId)); DBUG_RETURN(false); } _shmSegCreated = true; } // Attach if(!_attached){ if (!ndb_shm_attach()) { make_error_info(buf, sizeof(buf)); report_error(TE_SHM_UNABLE_TO_ATTACH_SEGMENT, buf); NDB_CLOSE_SOCKET(sockfd); DBUG_PRINT("error", ("Failed attach of shm seg to node %d", remoteNodeId)); DBUG_RETURN(false); } _attached = true; } // Send ok to server s_output.println("shm client 1 ok: %d", m_transporter_registry.m_shm_own_pid); int r= connect_common(sockfd); if (r) { // Wait for ok from server DBUG_PRINT("info", ("Wait for ok from server")); if (s_input.gets(buf, 256) == 0) { NDB_CLOSE_SOCKET(sockfd); DBUG_PRINT("error", ("No ok from server node %d", remoteNodeId)); DBUG_RETURN(false); } // Send ok to server s_output.println("shm client 2 ok"); DBUG_PRINT("info", ("Successfully connected client to node %d", remoteNodeId)); } NDB_CLOSE_SOCKET(sockfd); DBUG_RETURN(r); }
int my_munmap(void *addr, size_t len) { DBUG_ENTER("my_munmap"); DBUG_PRINT("mysys", ("unmap addr: %p", addr)); DBUG_RETURN(UnmapViewOfFile(addr) ? 0 : -1); }
MYRG_INFO *myrg_parent_open(const char *parent_name, int (*callback)(void*, const char*), void *callback_param) { MYRG_INFO *UNINIT_VAR(m_info); int rc; int errpos; int save_errno; int insert_method; uint length; uint child_count; File fd; IO_CACHE file_cache; char parent_name_buff[FN_REFLEN * 2]; char child_name_buff[FN_REFLEN]; DBUG_ENTER("myrg_parent_open"); rc= 1; errpos= 0; bzero((char*) &file_cache, sizeof(file_cache)); /* Open MERGE meta file. */ if ((fd= mysql_file_open(rg_key_file_MRG, fn_format(parent_name_buff, parent_name, "", MYRG_NAME_EXT, MY_UNPACK_FILENAME|MY_APPEND_EXT), O_RDONLY | O_SHARE, MYF(0))) < 0) goto err; /* purecov: inspected */ errpos= 1; if (init_io_cache(&file_cache, fd, 4 * IO_SIZE, READ_CACHE, 0, 0, MYF(MY_WME | MY_NABP))) goto err; /* purecov: inspected */ errpos= 2; /* Count children. Determine insert method. */ child_count= 0; insert_method= 0; while ((length= my_b_gets(&file_cache, child_name_buff, FN_REFLEN - 1))) { /* Remove line terminator. */ if (child_name_buff[length - 1] == '\n') child_name_buff[--length]= '\0'; /* Skip empty lines. */ if (!child_name_buff[0]) continue; /* purecov: inspected */ /* Skip comments, but evaluate insert method. */ if (child_name_buff[0] == '#') { if (!strncmp(child_name_buff + 1, "INSERT_METHOD=", 14)) { /* Compare buffer with global methods list: merge_insert_method. */ insert_method= find_type(child_name_buff + 15, &merge_insert_method, FIND_TYPE_BASIC); } continue; } /* Count the child. */ child_count++; } /* Allocate MERGE parent table structure. */ if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO) + child_count * sizeof(MYRG_TABLE), MYF(MY_WME | MY_ZEROFILL)))) goto err; /* purecov: inspected */ errpos= 3; m_info->open_tables= (MYRG_TABLE*) (m_info + 1); m_info->tables= child_count; m_info->merge_insert_method= insert_method > 0 ? insert_method : 0; /* This works even if the table list is empty. */ m_info->end_table= m_info->open_tables + child_count; if (!child_count) { /* Do not attach/detach an empty child list. */ m_info->children_attached= TRUE; } /* Call callback for each child. */ my_b_seek(&file_cache, 0); while ((length= my_b_gets(&file_cache, child_name_buff, FN_REFLEN - 1))) { /* Remove line terminator. */ if (child_name_buff[length - 1] == '\n') child_name_buff[--length]= '\0'; /* Skip empty lines and comments. */ if (!child_name_buff[0] || (child_name_buff[0] == '#')) continue; DBUG_PRINT("info", ("child: '%s'", child_name_buff)); /* Callback registers child with handler table. */ if ((rc= (*callback)(callback_param, child_name_buff))) goto err; /* purecov: inspected */ } end_io_cache(&file_cache); (void) mysql_file_close(fd, MYF(0)); mysql_mutex_init(rg_key_mutex_MYRG_INFO_mutex, &m_info->mutex, MY_MUTEX_INIT_FAST); m_info->open_list.data= (void*) m_info; mysql_mutex_lock(&THR_LOCK_open); myrg_open_list= list_add(myrg_open_list, &m_info->open_list); mysql_mutex_unlock(&THR_LOCK_open); DBUG_RETURN(m_info); /* purecov: begin inspected */ err: save_errno= my_errno; switch (errpos) { case 3: my_free(m_info); /* Fall through */ case 2: end_io_cache(&file_cache); /* Fall through */ case 1: (void) mysql_file_close(fd, MYF(0)); } my_errno= save_errno; DBUG_RETURN (NULL); /* purecov: end */ }
MY_DIR *my_dir(const char *path, myf MyFlags) { char *buffer; MY_DIR *result= 0; FILEINFO finfo; DYNAMIC_ARRAY *dir_entries_storage; MEM_ROOT *names_storage; DIR *dirp; struct dirent *dp; char tmp_path[FN_REFLEN + 2], *tmp_file; char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1]; DBUG_ENTER("my_dir"); DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags)); #if !defined(HAVE_READDIR_R) mysql_mutex_lock(&THR_LOCK_open); #endif dirp = opendir(directory_file_name(tmp_path,(char *) path)); #if defined(__amiga__) if ((dirp->dd_fd) < 0) /* Directory doesn't exists */ goto error; #endif if (dirp == NULL || ! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + sizeof(MEM_ROOT), MyFlags))) goto error; dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), ENTRIES_START_SIZE, ENTRIES_INCREMENT)) { my_free(buffer); goto error; } init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); /* MY_DIR structure is allocated and completly initialized at this point */ result= (MY_DIR*)buffer; tmp_file=strend(tmp_path); dp= (struct dirent*) dirent_tmp; while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp))) { if (!(finfo.name= strdup_root(names_storage, dp->d_name))) goto error; if (MyFlags & MY_WANT_STAT) { if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, sizeof(MY_STAT)))) goto error; memset(finfo.mystat, 0, sizeof(MY_STAT)); (void) strmov(tmp_file,dp->d_name); (void) my_stat(tmp_path, finfo.mystat, MyFlags); if (!(finfo.mystat->st_mode & MY_S_IREAD)) continue; } else finfo.mystat= NULL; if (push_dynamic(dir_entries_storage, (uchar*)&finfo)) goto error; } (void) closedir(dirp); #if !defined(HAVE_READDIR_R) mysql_mutex_unlock(&THR_LOCK_open); #endif result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; result->number_off_files= dir_entries_storage->elements; if (!(MyFlags & MY_DONT_SORT)) my_qsort((void *) result->dir_entry, result->number_off_files, sizeof(FILEINFO), (qsort_cmp) comp_names); DBUG_RETURN(result); error: #if !defined(HAVE_READDIR_R) mysql_mutex_unlock(&THR_LOCK_open); #endif my_errno=errno; if (dirp) (void) closedir(dirp); my_dirend(result); if (MyFlags & (MY_FAE | MY_WME)) { char errbuf[MYSYS_STRERROR_SIZE]; my_error(EE_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno)); } DBUG_RETURN((MY_DIR *) NULL); } /* my_dir */
int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, MI_INFO *(*callback)(void*), void *callback_param, my_bool *need_compat_check) { ulonglong file_offset; MI_INFO *myisam; int errpos; int save_errno; uint idx; uint child_nr; uint UNINIT_VAR(key_parts); uint min_keys; my_bool bad_children= FALSE; my_bool first_child= TRUE; DBUG_ENTER("myrg_attach_children"); DBUG_PRINT("myrg", ("handle_locking: %d", handle_locking)); /* This function can be called while another thread is trying to abort locks of this MERGE table. If the processor reorders instructions or write to memory, 'children_attached' could be set before 'open_tables' has all the pointers to the children. Use of a mutex here and in ha_myisammrg::store_lock() forces consistent data. */ mysql_mutex_lock(&m_info->mutex); errpos= 0; file_offset= 0; min_keys= 0; for (child_nr= 0; child_nr < m_info->tables; child_nr++) { if (! (myisam= (*callback)(callback_param))) { if (handle_locking & HA_OPEN_FOR_REPAIR) { /* An appropriate error should've been already pushed by callback. */ bad_children= TRUE; continue; } goto bad_children; } DBUG_PRINT("myrg", ("child_nr: %u table: '%s'", child_nr, myisam->filename)); /* Special handling when the first child is attached. */ if (first_child) { first_child= FALSE; m_info->reclength= myisam->s->base.reclength; min_keys= myisam->s->base.keys; key_parts= myisam->s->base.key_parts; if (*need_compat_check && m_info->rec_per_key_part) { my_free(m_info->rec_per_key_part); m_info->rec_per_key_part= NULL; } if (!m_info->rec_per_key_part) { if(!(m_info->rec_per_key_part= (ulong*) my_malloc(key_parts * sizeof(long), MYF(MY_WME)))) goto err; /* purecov: inspected */ errpos= 1; } bzero((char*) m_info->rec_per_key_part, key_parts * sizeof(long)); } /* Add MyISAM table info. */ m_info->open_tables[child_nr].table= myisam; m_info->open_tables[child_nr].file_offset= (my_off_t) file_offset; file_offset+= myisam->state->data_file_length; /* Check table definition match. */ if (m_info->reclength != myisam->s->base.reclength) { DBUG_PRINT("error", ("definition mismatch table: '%s' repair: %d", myisam->filename, (handle_locking & HA_OPEN_FOR_REPAIR))); if (handle_locking & HA_OPEN_FOR_REPAIR) { myrg_print_wrong_table(myisam->filename); bad_children= TRUE; continue; } goto bad_children; } m_info->options|= myisam->s->options; m_info->records+= myisam->state->records; m_info->del+= myisam->state->del; m_info->data_file_length+= myisam->state->data_file_length; if (min_keys > myisam->s->base.keys) min_keys= myisam->s->base.keys; /* purecov: inspected */ for (idx= 0; idx < key_parts; idx++) m_info->rec_per_key_part[idx]+= (myisam->s->state.rec_per_key_part[idx] / m_info->tables); } if (bad_children) goto bad_children; if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L) { my_errno= HA_ERR_RECORD_FILE_FULL; goto err; } /* Don't mark table readonly, for ALTER TABLE ... UNION=(...) to work */ m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA); m_info->keys= min_keys; m_info->last_used_table= m_info->open_tables; m_info->children_attached= TRUE; mysql_mutex_unlock(&m_info->mutex); DBUG_RETURN(0); bad_children: my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; err: save_errno= my_errno; switch (errpos) { case 1: my_free(m_info->rec_per_key_part); m_info->rec_per_key_part= NULL; } mysql_mutex_unlock(&m_info->mutex); my_errno= save_errno; DBUG_RETURN(1); }
int mrn_parse_table_param(MRN_SHARE *share, TABLE *table) { int i, error = 0; int title_length; const char *sprit_ptr[2]; const char *tmp_ptr, *start_ptr; char *params_string = NULL; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_element *part_elem; partition_element *sub_elem; #endif MRN_DBUG_ENTER_FUNCTION(); #ifdef WITH_PARTITION_STORAGE_ENGINE mrn_get_partition_info(share->table_name, share->table_name_length, table, &part_elem, &sub_elem); #endif #ifdef WITH_PARTITION_STORAGE_ENGINE for (i = 4; i > 0; i--) #else for (i = 2; i > 0; i--) #endif { const char *params_string_value = NULL; uint params_string_length = 0; switch (i) { #ifdef WITH_PARTITION_STORAGE_ENGINE case 4: if (!sub_elem || !sub_elem->part_comment) continue; DBUG_PRINT("info", ("mroonga create sub comment string")); params_string_value = sub_elem->part_comment; params_string_length = strlen(params_string_value); DBUG_PRINT("info", ("mroonga sub comment string=%s", params_string_value)); break; case 3: if (!part_elem || !part_elem->part_comment) continue; DBUG_PRINT("info", ("mroonga create part comment string")); params_string_value = part_elem->part_comment; params_string_length = strlen(params_string_value); DBUG_PRINT("info", ("mroonga part comment string=%s", params_string_value)); break; #endif case 2: if (LEX_STRING_IS_EMPTY(table->s->comment)) continue; DBUG_PRINT("info", ("mroonga create comment string")); params_string_value = table->s->comment.str; params_string_length = table->s->comment.length; DBUG_PRINT("info", ("mroonga comment string=%.*s", params_string_length, params_string_value)); break; default: if (LEX_STRING_IS_EMPTY(table->s->connect_string)) continue; DBUG_PRINT("info", ("mroonga create connect_string string")); params_string_value = table->s->connect_string.str; params_string_length = table->s->connect_string.length; DBUG_PRINT("info", ("mroonga connect_string=%.*s", params_string_length, params_string_value)); break; } if (!params_string_value) { continue; } { params_string = mrn_my_strndup(params_string_value, params_string_length, MYF(MY_WME)); if (!params_string) { error = HA_ERR_OUT_OF_MEM; goto error; } sprit_ptr[0] = params_string; while (sprit_ptr[0]) { if ((sprit_ptr[1] = strchr(sprit_ptr[0], ','))) { sprit_ptr[1]++; } tmp_ptr = sprit_ptr[0]; sprit_ptr[0] = sprit_ptr[1]; while (*tmp_ptr == ' ' || *tmp_ptr == '\r' || *tmp_ptr == '\n' || *tmp_ptr == '\t') tmp_ptr++; if (*tmp_ptr == '\0') continue; DBUG_PRINT("info", ("mroonga title_str=%s", tmp_ptr)); title_length = 0; start_ptr = tmp_ptr; while (*start_ptr != ' ' && *start_ptr != '\'' && *start_ptr != '"' && *start_ptr != '\0' && *start_ptr != '\r' && *start_ptr != '\n' && *start_ptr != '\t' && *start_ptr != ',') { title_length++; start_ptr++; } DBUG_PRINT("info", ("mroonga title_length=%u", title_length)); switch (title_length) { case 6: MRN_PARAM_STR("engine", engine); break; case 10: MRN_PARAM_STR("normalizer", normalizer); break; case 13: MRN_PARAM_STR("token_filters", token_filters); break; case 17: MRN_PARAM_STR("default_tokenizer", default_tokenizer); break; default: break; } } my_free(params_string); params_string = NULL; } } if (!share->engine && mrn_default_wrapper_engine) { share->engine_length = strlen(mrn_default_wrapper_engine); if ( !(share->engine = mrn_my_strndup(mrn_default_wrapper_engine, share->engine_length, MYF(MY_WME))) ) { error = HA_ERR_OUT_OF_MEM; goto error; } } if (share->engine) { LEX_STRING engine_name; if ( ( share->engine_length == MRN_DEFAULT_LEN && !strncasecmp(share->engine, MRN_DEFAULT_STR, MRN_DEFAULT_LEN) ) || ( share->engine_length == MRN_GROONGA_LEN && !strncasecmp(share->engine, MRN_GROONGA_STR, MRN_GROONGA_LEN) ) ) { my_free(share->engine); share->engine = NULL; share->engine_length = 0; } else { engine_name.str = share->engine; engine_name.length = share->engine_length; if (!(share->plugin = MRN_HA_RESOLVE_BY_NAME(&engine_name))) { my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), share->engine); error = ER_UNKNOWN_STORAGE_ENGINE; goto error; } share->hton = MRN_PLUGIN_DATA(share->plugin, handlerton *); share->wrapper_mode = TRUE; } }
int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length, int flag) { uint read_length,in_buff_length; my_off_t offset; uchar *in_buff_pos; DBUG_ENTER("_mi_read_cache"); DBUG_ASSERT(!(info->myflags & MY_ENCRYPT)); if (pos < info->pos_in_file) { read_length=length; if ((my_off_t) read_length > (my_off_t) (info->pos_in_file-pos)) read_length=(uint) (info->pos_in_file-pos); info->seek_not_done=1; if (mysql_file_pread(info->file, buff, read_length, pos, MYF(MY_NABP))) DBUG_RETURN(1); if (!(length-=read_length)) DBUG_RETURN(0); pos+=read_length; buff+=read_length; } if (pos >= info->pos_in_file && (offset= (my_off_t) (pos - info->pos_in_file)) < (my_off_t) (info->read_end - info->request_pos)) { in_buff_pos=info->request_pos+(uint) offset; in_buff_length= MY_MIN(length, (size_t) (info->read_end-in_buff_pos)); memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length); if (!(length-=in_buff_length)) DBUG_RETURN(0); pos+=in_buff_length; buff+=in_buff_length; } else in_buff_length=0; if (flag & READING_NEXT) { if (pos != (info->pos_in_file + (uint) (info->read_end - info->request_pos))) { info->pos_in_file=pos; /* Force start here */ info->read_pos=info->read_end=info->request_pos; /* Everything used */ info->seek_not_done=1; } else info->read_pos=info->read_end; /* All block used */ if (!_my_b_read(info,buff,length)) DBUG_RETURN(0); read_length=info->error; } else { info->seek_not_done=1; if ((read_length= mysql_file_pread(info->file, buff, length, pos, MYF(0))) == length) DBUG_RETURN(0); } if (!(flag & READING_HEADER) || (int) read_length == -1 || read_length+in_buff_length < 3) { DBUG_PRINT("error", ("Error %d reading next-multi-part block (Got %d bytes)", my_errno, (int) read_length)); if (!my_errno || my_errno == -1 || my_errno == HA_ERR_FILE_TOO_SHORT) my_errno= HA_ERR_WRONG_IN_RECORD; DBUG_RETURN(1); } bzero(buff+read_length,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length - read_length); DBUG_RETURN(0); } /* _mi_read_cache */
int mrn_add_column_param(MRN_SHARE *share, Field *field, int i) { int error; char *param_string = NULL; int title_length; char *sprit_ptr[2]; char *tmp_ptr, *start_ptr; MRN_DBUG_ENTER_FUNCTION(); if (share->wrapper_mode) { DBUG_RETURN(0); } DBUG_PRINT("info", ("mroonga create comment string")); if ( !(param_string = mrn_my_strndup(field->comment.str, field->comment.length, MYF(MY_WME))) ) { error = HA_ERR_OUT_OF_MEM; goto error_alloc_param_string; } DBUG_PRINT("info", ("mroonga comment string=%s", param_string)); sprit_ptr[0] = param_string; while (sprit_ptr[0]) { if ((sprit_ptr[1] = strchr(sprit_ptr[0], ','))) { *sprit_ptr[1] = '\0'; sprit_ptr[1]++; } tmp_ptr = sprit_ptr[0]; sprit_ptr[0] = sprit_ptr[1]; while (*tmp_ptr == ' ' || *tmp_ptr == '\r' || *tmp_ptr == '\n' || *tmp_ptr == '\t') tmp_ptr++; if (*tmp_ptr == '\0') continue; title_length = 0; start_ptr = tmp_ptr; while (*start_ptr != ' ' && *start_ptr != '\'' && *start_ptr != '"' && *start_ptr != '\0' && *start_ptr != '\r' && *start_ptr != '\n' && *start_ptr != '\t') { title_length++; start_ptr++; } switch (title_length) { case 4: MRN_PARAM_STR_LIST("type", col_type, i); break; case 5: MRN_PARAM_STR_LIST("flags", col_flags, i); break; case 12: MRN_PARAM_STR_LIST("groonga_type", col_type, i); break; default: break; } } if (param_string) my_free(param_string); DBUG_RETURN(0); error: if (param_string) my_free(param_string); error_alloc_param_string: DBUG_RETURN(error); }
my_string fn_format(my_string to, const char *name, const char *dsk, const char *form, int flag) { reg1 uint length; char dev[FN_REFLEN], buff[BUFF_LEN], *pos, *startpos; const char *ext; DBUG_ENTER("fn_format"); DBUG_PRINT("enter",("name: %s dsk: %s form: %s flag: %d", name,dsk,form,flag)); /* Kopiera & skippa enheten */ name+=(length=dirname_part(dev,(startpos=(my_string) name))); if (length == 0 || flag & 1) { (void) strmake(dev,dsk, sizeof(dev) - 2); /* Use given directory */ convert_dirname(dev); /* Fix to this OS */ } if (flag & 8) pack_dirname(dev,dev); /* Put in ./.. and ~/.. */ if (flag & 4) (void) unpack_dirname(dev,dev); /* Replace ~/.. with dir */ if ((pos=(char*)strchr(name,FN_EXTCHAR)) != NullS) { if ((flag & 2) == 0) /* Skall vi byta extension ? */ { length=strlength(name); /* Old extension */ ext = ""; } else { length=(uint) (pos-(char*) name); /* Change extension */ ext= form; } } else { length=strlength(name); /* Har ingen ext- tag nya */ ext=form; } if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN ) { /* To long path, return original */ uint tmp_length; if (flag & 64) return 0; tmp_length=strlength(startpos); DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %d",dev,ext,length)); (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1)); } else { if (to == startpos) { bmove(buff,(char*) name,length); /* Save name for last copy */ name=buff; } pos=strmake(strmov(to,dev),name,length); #ifdef FN_UPPER_CASE caseup_str(to); #endif #ifdef FN_LOWER_CASE casedn_str(to); #endif (void) strmov(pos,ext); /* Don't convert extension */ } /* Purify gives a lot of UMR errors when using realpath */ #if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH) if (flag & 16) { struct stat stat_buff; if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode))) { if (realpath(to,buff)) strmake(to,buff,FN_REFLEN-1); } } #endif DBUG_RETURN (to); } /* fn_format */