首先,只有在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;
\