示例#1
0
attribute attribute_find ( relation rel, char *name) {
/* attribute_find
 * Locates the given attribute, and returns an attribute structure
 */
	attribute catt,ratt;
	tuple ctuple;
	word anum;

	/* Get the first attribute */
	/* catt=attribute_findfirst(rel,&attribute_file); */
	catt=relation_attribute_readfirst(rel,&ctuple,&anum);

	/* Whilst the attribute is valid, and the attribute does
	 * not match the search criteria 
	 */
	while ( (catt!=NULL) && (name!=NULL) && (strcmp(attribute_name(catt),name)!=0) ) {

		/* Locate the next field */
		catt=relation_attribute_readnext(rel,&ctuple,catt,&anum);
	}

	/* Check to see if we actually found anything */
	if ( (catt!=NULL) && (name!=NULL) && (strcmp(attribute_name(catt),name)==0) ) {
	
		/* We're about to destroy the tuple, which will destroy the attribute
		 * we just found. Make a copy quick!
		 */
		/* Create a ptr to an attribute structure */
		ratt=(attribute_struct *) malloc(sizeof(attribute_struct));
	
		/* Check that the ptr was allocated. */
		check_assign(ratt,"attributes.attribute_find(cpy)");

		strcpy(attribute_name(ratt),attribute_name(catt));
		attribute_type(ratt)=attribute_type(catt);
		attribute_size(ratt)=attribute_size(catt);
		attribute_no(ratt)=attribute_no(catt);
		
		close_tuple(&ctuple,TUPLE_DISPOSE);

		/* Return the ptr */
		return(ratt);
	} else {
	
		/* Close the tuple */
		close_tuple(&ctuple,TUPLE_DISPOSE);

		/* Return nothing */	
		return(NULL);
	}
}
示例#2
0
文件: sort_ut.c 项目: flexxnn/LittleD
void test_sort_1(CuTest *tc)
{
	/* General variable declaration. */
	db_query_mm_t mm;
	char segment[2000];
	init_query_mm(&mm, segment, 2000);
	
	scan_t scan;
	sort_t sort;
	db_tuple_t t;
	db_eet_t oneExpr[1];
	db_uint8 oneOrder[1];
	db_eetnode_attr_t attrNode;
	attrNode.base.type = DB_EETNODE_ATTR;
	db_int intResult;
	
	puts("**********************************************************************");
	puts("Test 1: Sort test_rel3 using first attribute in ascending order.");
	fflush(stdout);
	
	oneExpr[0].size = (1*sizeof(db_eetnode_attr_t) + 0*sizeof(db_eetnode_dbint_t));
	oneExpr[0].nodes = malloc((size_t)oneExpr[0].size);
	oneExpr[0].stack_size = oneExpr[0].size;
	oneOrder[0] = (db_uint8)DB_TUPLE_ORDER_ASC;
	
	attrNode.pos = 0;
	attrNode.tuple_pos = 0;
	(*((db_eetnode_attr_t*)(oneExpr[0].nodes))) = attrNode;
	
	init_scan(&scan, "test_rel3", &mm);
	init_sort(&sort, (db_op_base_t*)(&scan), oneExpr, 1, oneOrder, &mm);
	init_tuple(&t, sort.base.header->tuple_size, sort.base.header->num_attr, &mm);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 1 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	//printf("Result of next call: %d\n", intResult);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 73 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 0 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 0 == intResult);
	
	close((db_op_base_t*)&sort, &mm);
	close((db_op_base_t*)&scan, &mm);
	free(oneExpr[0].nodes);
	close_tuple(&t, &mm);
	puts("**********************************************************************");
}
示例#3
0
文件: osijoin.c 项目: flexxnn/LittleD
/* Close the selection operator. */
db_int close_osijoin(osijoin_t *jp, db_query_mm_t *mmp)
{
	close_tuple(&(jp->ut), mmp);
	
	/* Free all header properties that were allocated */
	DB_QMM_BFREE(mmp, jp->base.header->size_name);
	DB_QMM_BFREE(mmp, jp->base.header->names);
	DB_QMM_BFREE(mmp, jp->base.header->types);
	DB_QMM_BFREE(mmp, jp->base.header->offsets);
	DB_QMM_BFREE(mmp, jp->base.header->sizes);
	DB_QMM_BFREE(mmp, jp->uexpr->nodes);
	DB_QMM_BFREE(mmp, jp->uexpr);
	
	/* Free the header itself. */
	DB_QMM_BFREE(mmp, jp->base.header);
	
	/* For the time being, do nothing! */
	return 1;
}
示例#4
0
文件: sort_ut.c 项目: flexxnn/LittleD
void test_sort_11(CuTest *tc)
{
	/* General variable declaration. */
	db_query_mm_t mm;
	char segment[2000];
	init_query_mm(&mm, segment, 2000);
	
	scan_t scan;
	sort_t sort;
	db_tuple_t t;
	db_eet_t twoExpr[2];
	db_uint8 twoOrder[2];
	db_eetnode_attr_t attrNode;
	attrNode.base.type = DB_EETNODE_ATTR;
	db_eetnode_t opNode;
	db_eetnode_t *arr_p;
	db_int intResult;
	
	puts("**********************************************************************");
	puts("Test 11: Sort fruit_stock_1 using two complex expressions.");
	fflush(stdout);
	twoExpr[0].size = (1*sizeof(db_eetnode_attr_t) + 0*sizeof(db_eetnode_dbstring_t)+ 1*sizeof(db_eetnode_t));
	twoExpr[0].nodes = malloc((size_t)twoExpr[0].size);
	twoExpr[0].stack_size = twoExpr[0].size;
	twoExpr[1].size = (2*sizeof(db_eetnode_attr_t) + 0*sizeof(db_eetnode_dbint_t)+ 1*sizeof(db_eetnode_t));
	twoExpr[1].nodes = malloc((size_t)twoExpr[1].size);
	twoExpr[1].stack_size = twoExpr[1].size;
	twoOrder[0] = DB_TUPLE_ORDER_ASC;
	twoOrder[1] = DB_TUPLE_ORDER_ASC;
	
	arr_p = twoExpr[0].nodes;
	
	attrNode.pos = 1;
	attrNode.tuple_pos = 0;
	(*((db_eetnode_attr_t*)(arr_p))) = attrNode;
	arr_p = ((db_eetnode_t*)(((db_eetnode_attr_t*)(arr_p))+1));
	
	opNode.type = DB_EETNODE_FUNC_LENGTH_DBSTRING;
	*arr_p = opNode;
	arr_p++;
	
	arr_p = twoExpr[1].nodes;
	
	attrNode.pos = 2;
	attrNode.tuple_pos = 0;
	(*((db_eetnode_attr_t*)(arr_p))) = attrNode;
	arr_p = ((db_eetnode_t*)(((db_eetnode_attr_t*)(arr_p))+1));
	
	attrNode.pos = 3;
	attrNode.tuple_pos = 0;
	(*((db_eetnode_attr_t*)(arr_p))) = attrNode;
	arr_p = ((db_eetnode_t*)(((db_eetnode_attr_t*)(arr_p))+1));
	
	opNode.type = DB_EETNODE_OP_MOD;
	*arr_p = opNode;
	arr_p++;
	
	init_scan(&scan, "fruit_stock_2", &mm);
	init_sort(&sort, (db_op_base_t*)(&scan), twoExpr, 2, twoOrder, &mm);
	init_tuple(&t, sort.base.header->tuple_size, sort.base.header->num_attr, &mm);
	
	// TODO: I really should change getintbypos and such to return to an address.
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	CuAssertTrue(tc, (1 << 0) + (1 << 1) + (1 << 2) == t.isnull[0]);
	//intResult = getintbypos(&t, 0, sort.base.header);
	//printf("Int value at position %d the tuple: %d\n", 0, intResult);
	//CuAssertTrue(tc, 3 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	CuAssertTrue(tc, (1 << 1) + (1 << 2) == t.isnull[0]);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 8 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	CuAssertTrue(tc, (1 << 1) == t.isnull[0]);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 3 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	CuAssertTrue(tc, (1 << 0) + (1 << 1) == t.isnull[0]);
	//intResult = getintbypos(&t, 0, sort.base.header);
	//printf("Int value at position %d the tuple: %d\n", 0, intResult);
	//CuAssertTrue(tc, 3 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	CuAssertTrue(tc, (1 << 2) == t.isnull[0]);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 5 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	CuAssertTrue(tc, (1 << 0) + (1 << 2) == t.isnull[0]);
	//intResult = getintbypos(&t, 0, sort.base.header);
	//printf("Int value at position %d the tuple: %d\n", 0, intResult);
	//CuAssertTrue(tc, 3 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	CuAssertTrue(tc, (1 << 0) == t.isnull[0]);
	//intResult = getintbypos(&t, 0, sort.base.header);
	//printf("Int value at position %d the tuple: %d\n", 0, intResult);
	//CuAssertTrue(tc, 3 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	CuAssertTrue(tc, 0 == t.isnull[0]);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 2 == intResult);
	

	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 0 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 0 == intResult);
	
	close((db_op_base_t*)&sort, &mm);
	close((db_op_base_t*)&scan, &mm);
	close_tuple(&t, &mm);
	free(twoExpr[0].nodes);
	free(twoExpr[1].nodes);
	puts("**********************************************************************");
}
示例#5
0
文件: sort_ut.c 项目: flexxnn/LittleD
void test_sort_9(CuTest *tc)
{
	/* General variable declaration. */
	db_query_mm_t mm;
	char segment[2000];
	init_query_mm(&mm, segment, 2000);
	
	scan_t scan;
	sort_t sort;
	db_tuple_t t;
	db_eet_t oneExpr[1];
	db_uint8 oneOrder[1];
	db_eetnode_attr_t attrNode;
	attrNode.base.type = DB_EETNODE_ATTR;
	db_eetnode_t opNode;
	db_eetnode_t *arr_p;
	db_int intResult;
	
	puts("**********************************************************************");
	puts("Test 9: Sort fruit_stock_1 using (3rd > 4th), in descending order.");
	fflush(stdout);
	oneExpr[0].size = (2*sizeof(db_eetnode_attr_t) + 0*sizeof(db_eetnode_dbint_t)+ 2*sizeof(db_eetnode_t));
	oneExpr[0].nodes = malloc((size_t)oneExpr[0].size);
	oneExpr[0].stack_size = oneExpr[0].size;
	oneOrder[0] = DB_TUPLE_ORDER_DESC;
	
	arr_p = oneExpr[0].nodes;
	
	attrNode.pos = 2;
	attrNode.tuple_pos = 0;
	(*((db_eetnode_attr_t*)(arr_p))) = attrNode;
	arr_p = ((db_eetnode_t*)(((db_eetnode_attr_t*)(arr_p))+1));
	
	attrNode.pos = 3;
	attrNode.tuple_pos = 0;
	(*((db_eetnode_attr_t*)(arr_p))) = attrNode;
	
	init_scan(&scan, "fruit_stock_1", &mm);
	init_sort(&sort, (db_op_base_t*)(&scan), oneExpr, 1, oneOrder, &mm);
	init_tuple(&t, sort.base.header->tuple_size, sort.base.header->num_attr, &mm);
	
	opNode.type = DB_EETNODE_OP_GT;
	*arr_p = opNode;
	arr_p++;
	
	opNode.type = DB_EETNODE_OP_NOT;
	*arr_p = opNode;
	arr_p++;
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 1 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 2 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 3 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 4 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 5 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 0 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 0 == intResult);
	
	close((db_op_base_t*)&sort, &mm);
	close((db_op_base_t*)&scan, &mm);
	close_tuple(&t, &mm);
	free(oneExpr[0].nodes);
	puts("**********************************************************************");
}
示例#6
0
文件: sort_ut.c 项目: flexxnn/LittleD
void test_sort_7(CuTest *tc)
{
	/* General variable declaration. */
	db_query_mm_t mm;
	char segment[2000];
	init_query_mm(&mm, segment, 2000);
	
	scan_t scan;
	sort_t sort;
	db_tuple_t t;
	db_eet_t twoExpr[2];
	db_uint8 twoOrder[2];
	db_eetnode_attr_t attrNode;
	attrNode.base.type = DB_EETNODE_ATTR;
	db_int intResult;
	
	puts("**********************************************************************");
	puts("Test 7: Sort fruit_stock_1 using 4th and 3rd attributes, in asc/desc order (respectively).");
	fflush(stdout);
	
	twoExpr[0].size = (1*sizeof(db_eetnode_attr_t) + 0*sizeof(db_eetnode_dbint_t));
	twoExpr[0].nodes = malloc((size_t)twoExpr[0].size);
	twoExpr[0].stack_size = twoExpr[0].size;
	
	twoExpr[1].size = (1*sizeof(db_eetnode_attr_t) + 0*sizeof(db_eetnode_dbint_t));
	twoExpr[1].nodes = malloc((size_t)twoExpr[1].size);
	twoExpr[1].stack_size = twoExpr[1].size;
	
	twoOrder[0] = DB_TUPLE_ORDER_ASC;
	twoOrder[1] = DB_TUPLE_ORDER_DESC;
	
	attrNode.pos = 3;
	attrNode.tuple_pos = 0;
	(*((db_eetnode_attr_t*)(twoExpr[0].nodes))) = attrNode;
	
	attrNode.pos = 2;
	attrNode.tuple_pos = 0;
	(*((db_eetnode_attr_t*)(twoExpr[1].nodes))) = attrNode;
	
	init_scan(&scan, "fruit_stock_1", &mm);
	init_sort(&sort, (db_op_base_t*)(&scan), twoExpr, 2, twoOrder, &mm);
	init_tuple(&t, sort.base.header->tuple_size, sort.base.header->num_attr, &mm);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 3 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 1 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 2 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 5 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 1 == intResult);
	intResult = getintbypos(&t, 0, sort.base.header);
	printf("Int value at position %d the tuple: %d\n", 0, intResult);
	CuAssertTrue(tc, 4 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 0 == intResult);
	
	intResult = next((db_op_base_t*)&sort, &t, &mm);
	CuAssertTrue(tc, 0 == intResult);
	
	close((db_op_base_t*)&sort, &mm);
	close((db_op_base_t*)&scan, &mm);
	close_tuple(&t, &mm);
	free(twoExpr[0].nodes);
	free(twoExpr[1].nodes);
	puts("**********************************************************************");
}
示例#7
0
文件: osijoin.c 项目: flexxnn/LittleD
/* This for now assumes that we are only doing a=b join conditions, where a
   b are from different relations. */
db_int setup_osijoin(osijoin_t *jp, db_query_mm_t *mmp)
{
	if (NULL == jp->tree || NULL == jp->tree->nodes)	return 0;
	
	db_int8 rindexed = -1, lindexed = -1;
	db_eetnode_t *cursor = jp->tree->nodes;
	db_eetnode_attr_t *lattrp, *rattrp;
	db_uint8 count = 0, lcount = 0, rcount = 0;
	
	// FIXME: See below.
	/* For now, we'll assume that things need to be indexed on a single attribute. */
	/* We also need to make the assumption that this condition only contains
	   stuff for this join specifically. */
	while (POINTERBYTEDIST(cursor, jp->tree->nodes) < jp->tree->size)
	{
		if (DB_EETNODE_ATTR == cursor->type)
		{
			if (1==((db_eetnode_attr_t*)cursor)->tuple_pos)
			{
				rattrp = (db_eetnode_attr_t*)cursor;
				rcount++;
				rindexed = findindexon((scan_t*)(jp->rchild), rattrp);
			}
			else if (0==((db_eetnode_attr_t*)cursor)->tuple_pos)
			{
				lattrp = (db_eetnode_attr_t*)cursor;
				lcount++;
				lindexed = findindexon((scan_t*)(jp->lchild), lattrp);
			}
			else
			{
				return 0;
			}
		}
		else if (DB_EETNODE_OP_EQ == cursor->type)
		{
			/* Do nothing, these are allowed. */	
		}
		else
			return 0;
		advanceeetnodepointer(&cursor, 1);
		count++;
	}
	
	if (3 != count || lcount > 1 || rcount > 1)
		return 0;
	
	db_op_base_t *indexed, *unindexed;
	jp->bitinfo = 1;
	if (rindexed < 0)
	{
		if (lindexed >= 0)
		{
			jp->indexon = (db_uint8)lindexed;
			indexed = jp->lchild;
			unindexed = jp->rchild;
			jp->bitinfo = 0;
			jp->uexpr = DB_QMM_BALLOC(mmp, sizeof(db_eet_t));
			jp->uexpr->size = sizeof(db_eetnode_attr_t);
			jp->uexpr->nodes = DB_QMM_BALLOC(mmp, sizeof(db_eetnode_attr_t));
			*((db_eetnode_attr_t*)(jp->uexpr->nodes)) = *rattrp;
			((db_eetnode_attr_t*)(jp->uexpr->nodes))->tuple_pos = 0;
			
			/* If our new tuple will not fit in old one, create a new one. */
			if (
			    ((((jp->rchild->header->num_attr) / 8) + ((jp->rchild->header->num_attr) % 8)) >
			     (((jp->lchild->header->num_attr) / 8) + ((jp->lchild->header->num_attr) % 8))) ||
			    ((jp->rchild->header->tuple_size) > (jp->lchild->header->tuple_size))
			)
			{
				close_tuple(&(jp->ut), mmp);
				init_tuple(&(jp->ut), jp->rchild->header->num_attr, jp->rchild->header->tuple_size, mmp);
				next(jp->rchild, &(jp->ut), mmp);
			}
		}
		else
			return 0;
	}
	else
	{
		jp->indexon = (db_uint8)rindexed;
		indexed = jp->rchild;
		unindexed = jp->lchild;
		jp->uexpr = DB_QMM_BALLOC(mmp, sizeof(db_eet_t));
		jp->uexpr->size = sizeof(db_eetnode_attr_t);
		jp->uexpr->nodes = DB_QMM_BALLOC(mmp, sizeof(db_eetnode_attr_t));
		*((db_eetnode_attr_t*)(jp->uexpr->nodes)) = *lattrp;
	}
	
	rewind_dbop(unindexed, mmp);
	DB_OSIJOIN_UPDATE_UMORE(jp->bitinfo, next(unindexed, &(jp->ut), mmp));
	
	db_uint8 lvalid = scan_find((scan_t*)indexed,
			jp->indexon,
			jp->uexpr,
			&(jp->ut),
			unindexed->header,
			mmp);
	DB_OSIJOIN_UPDATE_IVALID(jp->bitinfo, lvalid);
	
	jp->base.type = DB_OSIJOIN;
	return 1;
}
示例#8
0
文件: osijoin.c 项目: flexxnn/LittleD
db_int next_osijoin(osijoin_t *jp, db_tuple_t *next_tp, db_query_mm_t *mmp)
{
	/* Create necessary result variable. */
	db_int result = 0;
	
	db_tuple_t indexedtuple;
	
	/* Build arrays to be passed to eet evaluation engine.
	   Left = 0, Right = 1. */
	relation_header_t *hpa[2];
	db_tuple_t *tpa[2];
	
	hpa[0] = jp->lchild->header;
	hpa[1] = jp->rchild->header;
	
	// TODO: Reduce memory footprint.
	db_op_base_t *indexed, *unindexed;
	db_tuple_t *it;
	it = &indexedtuple;
	
	if (DB_OSIJOIN_RINDEXED(jp->bitinfo))
	{
		unindexed = jp->lchild;
		indexed   = jp->rchild;
		tpa[0]    = &(jp->ut);
		tpa[1]    = it;
	}
	else
	{
		unindexed = jp->rchild;
		indexed   = jp->lchild;
		tpa[0]    = it;
		tpa[1]    = &(jp->ut);
	}
	
	init_tuple(it, indexed->header->tuple_size, indexed->header->num_attr, mmp);
	
	db_uint8 lvalid;
	while (DB_OSIJOIN_UMORE(jp->bitinfo))
	{
		if (DB_OSIJOIN_IVALID(jp->bitinfo) && 1==next(indexed, it, mmp) && 1==evaluate_eet(jp->tree, &result, tpa, hpa, 0, mmp) && 1==result)
		{
		}
		else
		{
			DB_OSIJOIN_UPDATE_UMORE(jp->bitinfo, next(unindexed, &(jp->ut), mmp));
			lvalid = scan_find((scan_t*)indexed,
					jp->indexon,
					jp->uexpr,
					&(jp->ut),
					unindexed->header,
					mmp);
			DB_OSIJOIN_UPDATE_IVALID(jp->bitinfo, lvalid);
			continue;
		}
		
		/*** Do the join by combining the tuples
		 *   together. ***/
		/* Write out left tuples bytes into new tuple.
		 * */
		/* Write out left tuples isnull into new tuple.
		 * */
		
		db_int l_isnullsize = (db_int)(hpa[0]->num_attr) % 8 > 0
			? ((db_int)(hpa[0]->num_attr) / 8) + 1
			: ((db_int)(hpa[0]->num_attr) / 8);
		
		copytuplebytes(next_tp, tpa[0], 0, 0, hpa[0]->tuple_size);
		
		copytupleisnull(next_tp, tpa[0], 0, 0, l_isnullsize);
		
		/* Write out right tuples bytes directly after
		 * left tuples bytes. */
		copytuplebytes(next_tp, tpa[1], hpa[0]->tuple_size, 0, hpa[1]->tuple_size);
		
		/* Write out right tuples isnull into new tuple.
		 * */
		db_int i;
		db_int j = (db_int)(hpa[0]->num_attr);
		for (i = 0; i < (db_int)(hpa[1]->num_attr); ++i)
		{
			/* If this bit is 0 ... */
			if (0 == (tpa[1]->isnull[i/8] & (1 << (i % 8))))
			{
				next_tp->isnull[j/8] &= ~(1 << (j % 8));
			}
			else
			{
				next_tp->isnull[j/8] |= (1 << (j % 8));
			}
			j++;
		}
		
		close_tuple(it, mmp);
		return 1;
	}
	
	close_tuple(it, mmp);
	return 0;
}
示例#9
0
文件: dbindex.c 项目: flexxnn/LittleD
// FIXME: For now, this assumes equality for each of the expressions.
db_index_offset_t db_index_getoffset(scan_t *sp, db_uint8 indexon,
				db_eet_t *searchfor,
				db_tuple_t *comparator_tp,
				relation_header_t *comparator_hp,
				db_query_mm_t *mmp)
{
	if (sp->idx_meta_data.num_idx <= indexon)
		return -1;
	
	db_index_t index;
	if (1!=init_index(&index, sp->idx_meta_data.names[indexon]))
	{
		return -1;
	}
	
	if (DB_INDEX_TYPE_INLINE == index.type)
	{
		long first = sp->tuple_start;
		size_t total_size = sp->base.header->tuple_size + (sp->base.header->num_attr / 8);
		total_size += (sp->base.header->num_attr) % 8 > 0 ? 1 : 0;
		long last;
		if (sizeof(long)!=db_fileread(index.indexref, (unsigned char*)&(last), sizeof(long)))
		{
			return -1;
		}
		if (last > 0)
			last = first + (total_size * (last - 1));
		else
			last = first;
		long imin  = 0;
		long imax  = (last - first) / total_size;
		long imid;
		
		db_uint8 order[sp->idx_meta_data.num_expr[indexon]];
		int result;
		for (result = 0; result < sp->idx_meta_data.num_expr[indexon]; ++result)
			order[result] = DB_TUPLE_ORDER_ASC;
		
		db_tuple_t temp;
		init_tuple(&temp, sp->base.header->tuple_size, sp->base.header->num_attr, mmp);
		rewind_scan(sp, mmp);
		
		long i = -1;
		
		/* We binary search on expressions for first occurence. */
		while (imin <= imax)
		{
			imid = imin + ((imax - imin) / 2);
			
			db_filerewind(sp->relation);
			db_fileseek(sp->relation, (imid*(total_size))+first);
			next_scan(sp, &temp, mmp);
			
			/* arr[imid], key */
			if (NULL == comparator_hp)	/* FIXME: quick hack to let indexed scans work. */
			{
				result = getintbypos(&temp, ((db_int)searchfor), sp->base.header) - ((db_int)comparator_tp);
			}
			else
				result = cmp_tuple(&temp, comparator_tp,
					sp->base.header, comparator_hp,
					sp->idx_meta_data.exprs[indexon],
					searchfor,
					sp->idx_meta_data.num_expr[indexon],
					order, 1, mmp);
			
			if (result < 0)
				imin = imid + 1;
			else if (result > 0)
				imax = imid - 1;
			else if (imin != imid)
				imax = imid;
			else
			{
				i = imid;
				break;
			}
				
		}
		
		if (i <= -1)	i = imin;
		i = (first + (i*total_size));
		
		db_filerewind(sp->relation);
		db_fileseek(sp->relation, i);
		next_scan(sp, &temp, mmp);
		
		/* FIXME: quick hack to let indexed scans work. (first part of the condition) */
		if (NULL != comparator_hp && 0!=cmp_tuple(&temp, comparator_tp,
				sp->base.header, comparator_hp,
				sp->idx_meta_data.exprs[indexon],
				searchfor,
				sp->idx_meta_data.num_expr[indexon],
				order, 1, mmp))
			i = -1;
		
		close_tuple(&temp, mmp);
		close_index(&index);
		
		return i;
	}
	
	return -1;
}