NLJ的新代码(2)

首先,只有在DBLIB_ENABLED启动的时候,才执行我们的代码。

if (DBLIB_ENABLED)






第一个变量用来表明是第几次调用了NestLoop函数。
第二个变量用来盛放结果啊,不过为什么要是static呢?

static int dblib_nestloop_num = 0;
static TupleTableSlot *dblib_result_tupleslot = NULL;






只有不是index scan的时候我们才加速哦

if (outerPlan->type != T_IndexScanState 
	&& innerPlan->type != T_IndexScanState)






接着看代码:
下面的两个东西的第一个是用来表示我们算好的一对一对index

第二个是输出的结果的长度

第三四五六个是用来存放那些表的数据啦,它是一个四个数一组的数列哦!
这个必须static的,因为下一次调用的时候还必须是原来的东西才对哦。。

还有是不是空的啦

static int *dblib_output_qual_index = NULL;
static int dblib_output_index_col = 0;


static Datum *dblib_outer_output_datums = NULL;
static bool *dblib_outer_output_tts_isnull = NULL;

static Datum *dblib_inner_output_datums = NULL;
static bool *dblib_inner_output_tts_isnull = NULL;







在这里插入图片描述
其他的还有每个变量在结果表的index啦啦啦啦。很简单的。

static int *dblib_innerresult_attnum = NULL;
static int *dblib_outerresult_attnum = NULL;
static int	*dblib_inner_var_attnum = NULL;
static int *dblib_outer_var_attnum = NULL;
static int dblib_resultattr_valid_num = 0, //结果表有几个数
		   dblib_innerattr_valid_num = 0,//内表有几个数呢
		   dblib_outerattr_valid_num = 0;//外表有几个数呢
static int dblib_outer_col = 0, dblib_inner_col = 0;//内外表有几列






接着继续看代码:
第一个是临时变量,这没啥
第二个,第三个也是得啊

TupleTableSlot *dblib_temp_tupleslot;
Datum *dblib_input_inner = NULL;//仅用来盛放join列,仅仅使用一次
Datum *dblib_input_outer = NULL;//仅用来盛放join列,仅仅使用一次






下面的都是一些辅助性的东西

int dblib_i = 0;
int dblib_inner_fetch_attnum, //内表要抓取多少数呢
			dblib_outer_fetch_attnum, //外表要抓取多少数呢
			dblib_inner_join_attnum,//连接列
			dblib_outer_join_attnum;//连接列
unsigned int dblib_join_funcid;//函数标识






这句话的意思只有当是第一次loop的时候我们才进行下面的操作

	if (dblib_nestloop_num == 0) {






下面就是分配内存啦啊。
下面这三个是分配Datum和一对一对index使用的哦!

dblib_input_inner = (Datum *)malloc(DBLIB_INPUTSLOTS_NUM * sizeof(Datum));
dblib_input_outer = (Datum *)malloc(DBLIB_INPUTSLOTS_NUM * sizeof(Datum));

dblib_output_qual_index = (int *)malloc(2 * DBLIB_OUTPUTSLOTS_NUM * sizeof(int));






这个是四位长度的数组楼,

dblib_innerresult_attnum = (int *)malloc(DBLIB_ATTR_NUM * sizeof(int));
dblib_outerresult_attnum = (int *)malloc(DBLIB_ATTR_NUM * sizeof(int));
dblib_inner_var_attnum = (int *)malloc(DBLIB_ATTR_NUM * sizeof(int));
dblib_outer_var_attnum = (int *)malloc(DBLIB_ATTR_NUM * sizeof(int));






这个代码是分别是将内层取几个属性,

外层几个属性

内层join列在tts->value的index

外层join列在tts->value的index

函数标识

for (; dblib_i < joinqual->steps_len; dblib_i++)
{
	switch ((joinqual->steps + dblib_i)->opcode)
	{
		case EEOP_INNER_FETCHSOME:
			dblib_inner_fetch_attnum = (joinqual->steps + dblib_i)->d.fetch.last_var;
						break;
		case EEOP_OUTER_FETCHSOME:
			dblib_outer_fetch_attnum = (joinqual->steps + dblib_i)->d.fetch.last_var;
						break;
		case EEOP_INNER_VAR:
			dblib_inner_join_attnum = (joinqual->steps + dblib_i)->d.var.attnum;
						break;
		case EEOP_OUTER_VAR:
			dblib_outer_join_attnum = (joinqual->steps + dblib_i)->d.var.attnum;
						break;
		case EEOP_FUNCEXPR_STRICT:
			dblib_join_funcid = (joinqual->steps + dblib_i)->d.func.finfo->fn_oid;
						break;

		default:
						;			
	}
}






这个代码是分别是将内层取几个属性更新下,

外层几个属性更新下

下面两个是这个意思:

  • 我每次得到一个变量,我就把他在我自己的tts->value的位置记下来,当然还要把他在结果的index记下来。
  • 当然,要记得把dblib_outerattr_valid_num++;
ExprState *dblib_pi_state = &(node->js.ps.ps_ProjInfo->pi_state);

for (dblib_i = 0; dblib_i < dblib_pi_state->steps_len; dblib_i++)
{
	switch ((dblib_pi_state->steps + dblib_i)->opcode)
	{
	case EEOP_INNER_FETCHSOME:
		if (dblib_inner_fetch_attnum < (dblib_pi_state->steps + dblib_i)->d.fetch.last_var)
			dblib_inner_fetch_attnum = (dblib_pi_state->steps + dblib_i)->d.fetch.last_var;
		break;
	case EEOP_OUTER_FETCHSOME:
		if (dblib_outer_fetch_attnum < (dblib_pi_state->steps + dblib_i)->d.fetch.last_var)
			dblib_outer_fetch_attnum = (dblib_pi_state->steps + dblib_i)->d.fetch.last_var;
		break;
	case EEOP_ASSIGN_INNER_VAR:
		dblib_innerresult_attnum[dblib_innerattr_valid_num] =
							(dblib_pi_state->steps + dblib_i)->d.assign_var.resultnum;
		dblib_inner_var_attnum[dblib_innerattr_valid_num] =
							(dblib_pi_state->steps + dblib_i)->d.assign_var.attnum;
		dblib_innerattr_valid_num++;
		break;
	case EEOP_ASSIGN_OUTER_VAR:
		dblib_outerresult_attnum[dblib_outerattr_valid_num] =
							(dblib_pi_state->steps + dblib_i)->d.assign_var.resultnum;
		dblib_outer_var_attnum[dblib_outerattr_valid_num] =
							(dblib_pi_state->steps + dblib_i)->d.assign_var.attnum;
		dblib_outerattr_valid_num++;
		break;
	default:
			;		
	}				
}






下面的代码的意思是只要结果的列个数大于0,就为结果们datum申请空间。

/*
* initialize dblib_output_datums
*/
dblib_resultattr_valid_num = dblib_innerattr_valid_num +dblib_outerattr_valid_num;
if (dblib_resultattr_valid_num > 0) {

	dblib_outer_output_datums = (Datum *)malloc(DBLIB_OUTPUTSLOTS_NUM *
						dblib_outerattr_valid_num * sizeof(Datum));

	dblib_outer_output_tts_isnull = (bool *)malloc(DBLIB_OUTPUTSLOTS_NUM *
						dblib_outerattr_valid_num * sizeof(bool));

	dblib_inner_output_datums = (Datum *)malloc(DBLIB_OUTPUTSLOTS_NUM *
						dblib_innerattr_valid_num * sizeof(Datum));

	dblib_inner_output_tts_isnull = (bool *)malloc(DBLIB_OUTPUTSLOTS_NUM *
						dblib_innerattr_valid_num * sizeof(bool));
	}






下面的代码是将outer层的tuple的全部取出来投放到dblib_outer_output_datums以及把需要join的东西也去出来
放到dblib_input_outer 里

/*
				* getting outer tuples and result slots related to outer tuples
				*/
				dblib_i = 0;
				ENL1_printf("DBLIB getting outer tuples");
				dblib_temp_tupleslot = ExecProcNode(outerPlan);
				while (!(TupIsNull(dblib_temp_tupleslot)) && (dblib_i < DBLIB_INPUTSLOTS_NUM))
				{
					/* Assign outer slots inputs*/
					//(joinqual->steps + 1)->d.fetch.last_var, joinqual->steps->d.var.attnum
					slot_getsomeattrs(dblib_temp_tupleslot, dblib_outer_fetch_attnum);
					/* Assign outer intputs*/
					*(dblib_input_outer + dblib_i) = dblib_temp_tupleslot->tts_values[dblib_outer_join_attnum];
					/* Assign output datum*/
					for (int dblib_j = 0; dblib_j < dblib_outerattr_valid_num; dblib_j++)
					{
						int dblib_temp_index1 = dblib_i * dblib_outerattr_valid_num +
							dblib_j;
						int dblib_temp_index2 = dblib_outer_var_attnum[dblib_j];

						dblib_outer_output_datums[dblib_temp_index1] =
							dblib_temp_tupleslot->tts_values[dblib_temp_index2];
						dblib_outer_output_tts_isnull[dblib_temp_index1] =
							dblib_temp_tupleslot->tts_isnull[dblib_temp_index2];

					}

					dblib_temp_tupleslot = ExecProcNode(outerPlan);
					dblib_i++;
				}
				dblib_outer_col = dblib_i;





\

dblib_i = 0;
ENL1_printf("DBLIB getting inner tuples");
dblib_temp_tupleslot = ExecProcNode(innerPlan);
while (!(TupIsNull(dblib_temp_tupleslot)) && (dblib_i < DBLIB_INPUTSLOTS_NUM))
{
	/* Assign outer slots inputs */
	//(joinqual->steps + 1)->d.fetch.last_var, joinqual->steps->d.var.attnum
	slot_getsomeattrs(dblib_temp_tupleslot, dblib_inner_fetch_attnum);
		/* Assign inner inputs*/
	*(dblib_input_inner + dblib_i) = dblib_temp_tupleslot->tts_values[dblib_inner_join_attnum];
	/* Assign output datum*/
	for (int dblib_j = 0; dblib_j < dblib_innerattr_valid_num; dblib_j++)
	{

		int dblib_temp_index1 = dblib_i * dblib_innerattr_valid_num +
							dblib_j;
		int dblib_temp_index2 = dblib_inner_var_attnum[dblib_j];

		dblib_inner_output_datums[dblib_temp_index1] =
							dblib_temp_tupleslot->tts_values[dblib_temp_index2];
		dblib_inner_output_tts_isnull[dblib_temp_index1] =
							dblib_temp_tupleslot->tts_isnull[dblib_temp_index2];
	}

	dblib_temp_tupleslot = ExecProcNode(innerPlan);
	dblib_i++;
}
dblib_inner_col = dblib_i;





\

猜你喜欢

转载自blog.csdn.net/zhoutianzi12/article/details/90899413