Esempio n. 1
0
/*
 * the main index function.
 * caller provides an index chain which is the current traversal of index
 * pages from the root page to the leaf.  Initially passed as blank, 
 * mdb_index_find_next will store it's state information here. Each invocation
 * then picks up where the last one left off, allowing us to scroll through
 * the index one by one.
 *
 * Sargs are applied here but also need to be applied on the whole row b/c
 * text columns may return false positives due to hashing and non-index
 * columns with sarg values can't be tested here.
 */
int
mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row)
{
	MdbIndexPage *ipg;
	int passed = 0;
	int idx_sz;
	int idx_start = 0;
	MdbColumn *col;

	ipg = mdb_index_read_bottom_pg(mdb, idx, chain);

	/*
	 * loop while the sargs don't match
	 */
	do {
		ipg->len = 0;
		/*
		 * if no more rows on this leaf, try to find a new leaf
		 */
		if (!mdb_index_find_next_on_page(mdb, ipg)) {
			if (!chain->clean_up_mode) {
				if (!(ipg = mdb_index_unwind(mdb, idx, chain)))
					chain->clean_up_mode = 1;
			}
			if (chain->clean_up_mode) {
				//fprintf(stdout,"in cleanup mode\n");

				if (!chain->last_leaf_found) return 0;
				mdb_read_pg(mdb, chain->last_leaf_found);
				chain->last_leaf_found = mdb_pg_get_int24(mdb, 0x0c);
				//printf("next leaf %lu\n", chain->last_leaf_found);
				mdb_read_pg(mdb, chain->last_leaf_found);
				/* reuse the chain for cleanup mode */
				chain->cur_depth = 1;
				ipg = &chain->pages[0];
				mdb_index_page_init(ipg);
				ipg->pg = chain->last_leaf_found;
				//printf("next on page %d\n",
				if (!mdb_index_find_next_on_page(mdb, ipg))
					return 0;
			}
		}
		*row = mdb->pg_buf[ipg->offset + ipg->len - 1];
#if 0
		printf("page: ");
		buffer_dump(mdb->pg_buf, ipg->offset+ipg->len-4, ipg->offset+ipg->len-2);
#endif
		*pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
#if 0
		printf("row = %d pg = %lu ipg->pg = %lu offset = %lu len = %d\n", *row, *pg, ipg->pg, ipg->offset, ipg->len);
#endif
		col=g_ptr_array_index(idx->table->columns,idx->key_col_num[0]-1);
		idx_sz = mdb_col_fixed_size(col);
		/* handle compressed indexes, single key indexes only? */
		if (idx->num_keys==1 && idx_sz>0 && ipg->len - 4 < idx_sz) {
#if 0
			printf("short index found\n");
			buffer_dump(ipg->cache_value, 0, idx_sz);
#endif
			memcpy(&ipg->cache_value[idx_sz - (ipg->len - 4)], &mdb->pg_buf[ipg->offset], ipg->len);
#if 0
			buffer_dump(ipg->cache_value, 0, idx_sz);
#endif
		} else {
			idx_start = ipg->offset + (ipg->len - 4 - idx_sz);
			memcpy(ipg->cache_value, &mdb->pg_buf[idx_start], idx_sz);
		}

		//idx_start = ipg->offset + (ipg->len - 4 - idx_sz);
		passed = mdb_index_test_sargs(mdb, idx, ipg->cache_value, idx_sz);

//		printf("passed=%d\n", passed);

		buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
		ipg->offset += ipg->len;

	} while (!passed);

#if 0
	fprintf(stdout,"len = %d pos %d\n", ipg->len, ipg->len);
	buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
#endif

	return ipg->len;
}
Esempio n. 2
0
int
convert_field(MdbColumn *col, char *s, MdbField *field)
{
	char *c;
	MdbAny any;

	field->colnum = col->col_num;
	field->is_fixed = col->is_fixed;
	switch (col->col_type) {
		case MDB_TEXT:
			field->value = g_strdup(s);
			field->siz = strlen(s);
			break;
		case MDB_BYTE:
			any.i = strtol(s, &c, 16);
			if (*c) return 1;
			field->siz = mdb_col_fixed_size(col);
			field->value = g_malloc(field->siz);
			((unsigned char *)field->value)[0] = any.i;
			break;
		case MDB_INT:
			any.i = strtol(s, &c, 16);
			if (*c) return 1;
			field->siz = mdb_col_fixed_size(col);
			field->value = g_malloc(field->siz);
			mdb_put_int16(field->value, 0, any.i);
			break;
		case MDB_LONGINT:
			any.i = strtol(s, &c, 16);
			if (*c) return 1;
			field->siz = mdb_col_fixed_size(col);
			field->value = g_malloc(field->siz);
			mdb_put_int32(field->value, 0, any.i);
			break;
		case MDB_BOOL:
			if (*s == '1') {
				field->is_null = 1;
			} else if (*s == '0') {
				field->is_null = 0;
			} else {
				fprintf(stderr, "%c is not a valid value for type BOOLEAN\n", *s);
				return 1;
			}
			/*
		case MDB_FLOAT:
			any.d = strtod(s, &c);
			if (*c) return 1;
			field.value = g_malloc(mdb_col_fixed_size(col));
			mdb_put_single(field.value, 0, any.i);
			break;
		case MDB_DOUBLE:
			any.d = strtod(s, &c);
			if (*c) return 1;
			field.value = g_malloc(mdb_col_fixed_size(col));
			mdb_put_double(field.value, 0, any.i);
			break;
		*/
			/*
		case MDB_MONEY:
		case MDB_SDATETIME:
		case MDB_OLE:
		case MDB_MEMO:
		case MDB_REPID:
		case MDB_NUMERIC:
			*/
		default:
			fprintf(stderr,"Conversion of type %02x not supported yet.\n", col->col_type);
			return 1;
			break;
	}
	return 0;
}