⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pass1.c

📁 firebird源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* Insure that variable names do not duplicate parameter names */	if (variables = input->nod_arg [e_prc_dcls])	    {	    for (ptr = variables->nod_arg, end = ptr + variables->nod_count;		 ptr < end; ptr++)		{		field = (FLD) (*ptr)->nod_arg [e_dfl_field];		DEV_BLKCHK (field, type_fld);		if (parameters = input->nod_arg [e_prc_inputs])		    for (ptr2 = parameters->nod_arg, end2 = ptr2 + parameters->nod_count;			 ptr2 < end2; ptr2++)			{			field2 = (FLD) (*ptr2)->nod_arg [e_dfl_field];			DEV_BLKCHK (field2, type_fld);			if (!strcmp (field->fld_name, field2->fld_name))			    ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -901, 				gds_arg_gds, gds__dsql_var_conflict,				gds_arg_string, field->fld_name, 				0);			}		if (parameters = input->nod_arg [e_prc_outputs])		    for (ptr2 = parameters->nod_arg, end2 = ptr2 + parameters->nod_count;			 ptr2 < end2; ptr2++)			{			field2 = (FLD) (*ptr2)->nod_arg [e_dfl_field];			DEV_BLKCHK (field2, type_fld);			if (!strcmp (field->fld_name, field2->fld_name))			    ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -901, 				gds_arg_gds, gds__dsql_var_conflict,				gds_arg_string, field->fld_name, 				0);			}		}	    }	return input;    case nod_assign:	node = MAKE_node (input->nod_type, input->nod_count);	node->nod_arg [0] = PASS1_node (request, input->nod_arg [0], proc_flag);	node->nod_arg [1] = PASS1_node (request, input->nod_arg [1], proc_flag);	break;    case nod_commit:	if ((input->nod_arg [e_commit_retain]) && 	    (input->nod_arg [e_commit_retain]->nod_type == nod_commit_retain))	    request->req_type = REQ_COMMIT_RETAIN;	else	    request->req_type = REQ_COMMIT;	return input;    case nod_delete:	node = pass1_delete (request, input);	if (request->req_error_handlers)	    {	    temp = MAKE_node (nod_list, 3);	    temp->nod_arg [0] = MAKE_node (nod_start_savepoint, 0);	    temp->nod_arg [1] = node;	    temp->nod_arg [2] = MAKE_node (nod_end_savepoint, 0);	    node = temp;	    }	break;    case nod_exec_procedure:	if (!proc_flag)	    {	    name = (STR) input->nod_arg [e_exe_procedure];	    DEV_BLKCHK (name, type_str);	    if (!(request->req_procedure = METD_get_procedure (request, name)))		ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -204,		    gds_arg_gds, gds__dsql_procedure_err, 		    gds_arg_gds, gds__random, 		    gds_arg_string, name->str_data, 		    0);	    request->req_type = REQ_EXEC_PROCEDURE;	    }	node = MAKE_node (input->nod_type, input->nod_count);	node->nod_arg [e_exe_procedure] = input->nod_arg [e_exe_procedure];	node->nod_arg [e_exe_inputs] = PASS1_node (request,				   input->nod_arg [e_exe_inputs], proc_flag);	if (temp = input->nod_arg [e_exe_outputs])	    node->nod_arg [e_exe_outputs] = (temp->nod_type == nod_all) ?		explode_outputs (request, request->req_procedure) :		PASS1_node (request, temp, proc_flag);	if (!proc_flag)	    {	    if (node->nod_arg [e_exe_inputs])		count = node->nod_arg [e_exe_inputs]->nod_count;	    else 		count = 0;    	    if (count != request->req_procedure->prc_in_count)		ERRD_post (gds__prcmismat, gds_arg_string, name->str_data, 0);	    if (count)	        {		/* Initialize this stack variable, and make it look like a node */		memset ((SCHAR *)&desc_node, 0, sizeof (desc_node));		desc_node.nod_header.blk_type = type_nod;	        for (ptr = node->nod_arg [e_exe_inputs]->nod_arg,		 	field = request->req_procedure->prc_inputs;		 	field;		 	ptr++, field = field->fld_next)		    {		    DEV_BLKCHK (field, type_fld);		    DEV_BLKCHK (*ptr, type_nod);		    MAKE_desc_from_field (&desc_node.nod_desc, field);		    set_parameter_type (*ptr, &desc_node, FALSE);		    }		}	    }	break;    case nod_for_select:	node = MAKE_node (input->nod_type, input->nod_count);        node->nod_flags = input->nod_flags;	cursor = node->nod_arg [e_flp_cursor] = input->nod_arg [e_flp_cursor];	if (cursor && (procedure = request->req_ddl_node) &&		    ((procedure->nod_type == nod_def_procedure) ||		     (procedure->nod_type == nod_mod_procedure) ||			 procedure->nod_type == nod_def_trigger ||			 procedure->nod_type == nod_mod_trigger))	    {	    cursor->nod_arg [e_cur_next] = procedure->nod_arg [e_prc_cursors];	    procedure->nod_arg [e_prc_cursors] = cursor;	    cursor->nod_arg [e_cur_context] = node;	    }	node->nod_arg [e_flp_select] = PASS1_statement (request,				   input->nod_arg [e_flp_select], proc_flag);	into_in = input->nod_arg [e_flp_into];	node->nod_arg [e_flp_into] = into_out =	    MAKE_node (into_in->nod_type, into_in->nod_count);	ptr2 = into_out->nod_arg;	for (ptr = into_in->nod_arg, end = ptr + into_in->nod_count;	     ptr < end; ptr++)	    {	    DEV_BLKCHK (*ptr, type_nod);	    *ptr2++ = PASS1_node (request, *ptr, proc_flag);	    DEV_BLKCHK (*(ptr2-1), type_nod);	    }	if (input->nod_arg [e_flp_action])	{		/* CVC: Let's add the ability to BREAK the for_select same as the while.	    but only if the command is FOR SELECT, otherwise we have singular SELECT. */	    node->nod_arg [e_flp_number] = (NOD) request->req_loop_number++;	    node->nod_arg [e_flp_action] = PASS1_statement (request,				   input->nod_arg [e_flp_action], proc_flag);	}	if (cursor &&	    procedure &&	    ((procedure->nod_type == nod_def_procedure) ||	     (procedure->nod_type == nod_mod_procedure) ||		 procedure->nod_type == nod_def_trigger ||		 procedure->nod_type == nod_mod_trigger))	    procedure->nod_arg [e_prc_cursors] = cursor->nod_arg [e_cur_next];	if (request->req_error_handlers && 		(input->nod_flags & NOD_SINGLETON_SELECT))	    {	    temp = MAKE_node (nod_list, 3);	    temp->nod_arg [0] = MAKE_node (nod_start_savepoint, 0);	    temp->nod_arg [1] = node;	    temp->nod_arg [2] = MAKE_node (nod_end_savepoint, 0);	    node = temp;	    }	break;    case nod_get_segment:    case nod_put_segment:	pass1_blob (request, input);	return input;    case nod_if:	node = MAKE_node (input->nod_type, input->nod_count);	node->nod_arg [e_if_condition] = PASS1_node (request,			 input->nod_arg [e_if_condition], proc_flag);	node->nod_arg [e_if_true] = PASS1_statement (request,				   input->nod_arg [e_if_true], proc_flag);	if (input->nod_arg [e_if_false])	    node->nod_arg [e_if_false] =		PASS1_statement (request, input->nod_arg [e_if_false],				 proc_flag);	else	    node->nod_arg [e_if_false] = NULL;	break;    case nod_exception_stmt:	node = input;	if (request->req_error_handlers)	    {	    temp = MAKE_node (nod_list, 3);	    temp->nod_arg [0] = MAKE_node (nod_start_savepoint, 0);	    temp->nod_arg [1] = input;	    temp->nod_arg [2] = MAKE_node (nod_end_savepoint, 0);	    node = temp;	    }	return node;    case nod_insert:	node = pass1_insert (request, input);	if (request->req_error_handlers)	    {	    temp = MAKE_node (nod_list, 3);	    temp->nod_arg [0] = MAKE_node (nod_start_savepoint, 0);	    temp->nod_arg [1] = node;	    temp->nod_arg [2] = MAKE_node (nod_end_savepoint, 0);	    node = temp;	    }	break;    case nod_block:	if (input->nod_arg [e_blk_errs])	    request->req_error_handlers++;	else	    { 	    input->nod_count = 1;	    if (!request->req_error_handlers)		input->nod_type = nod_list;	    }    case nod_list:	node = MAKE_node (input->nod_type, input->nod_count);	ptr2 = node->nod_arg;	for (ptr = input->nod_arg, end = ptr + input->nod_count;	     ptr < end; ptr++)	    {	    DEV_BLKCHK (*ptr, type_nod);	    if ((*ptr)->nod_type == nod_assign)		*ptr2++ = PASS1_node (request, *ptr, proc_flag);	    else		*ptr2++ = PASS1_statement (request, *ptr, proc_flag);	    DEV_BLKCHK (*(ptr2-1), type_nod);	    }	if (input->nod_type == nod_block && input->nod_arg [e_blk_errs])	    request->req_error_handlers--;	return node;    case nod_on_error:	node = MAKE_node (input->nod_type, input->nod_count);	node->nod_arg [e_err_errs] = input->nod_arg [e_err_errs];	node->nod_arg [e_err_action] = PASS1_statement (request,				input->nod_arg [e_err_action], proc_flag);	return node;    case nod_post:	node = MAKE_node (input->nod_type, input->nod_count);	node->nod_arg [e_pst_event] = PASS1_node (request,				input->nod_arg [e_pst_event], proc_flag);	return node;    case nod_rollback:	request->req_type = REQ_ROLLBACK;	return input;    case nod_exit:	if (request->req_flags & REQ_trigger)	    ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, 		gds_arg_gds, gds__token_err,    /* Token unknown */		gds_arg_gds, gds__random, 		gds_arg_string, "EXIT", 0);	return input;    case nod_breakleave:	input->nod_arg [e_break_number] = (NOD) (request->req_loop_number - 1);	return input;    case nod_exec_sql:	node = MAKE_node (input->nod_type, input->nod_count);	node->nod_arg [e_exec_vc] = PASS1_node (request,				input->nod_arg [e_exec_vc], proc_flag);	return node;    case nod_return:	if (request->req_flags & REQ_trigger)	    ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, 		gds_arg_gds, gds__token_err,    /* Token unknown */		gds_arg_gds, gds__random, 		gds_arg_string, "RETURN", 0);	input->nod_arg [e_rtn_procedure] = request->req_ddl_node;	return input;    case nod_select:	node = PASS1_rse (request, input->nod_arg [0], input->nod_arg [1]);	if (input->nod_arg [2])	    {	    request->req_type = REQ_SELECT_UPD;	    request->req_flags |= REQ_no_batch;	    break;	    }	/*	** If there is a union without ALL or order by or a select distinct  	** buffering is OK even if stored procedure occurs in the select	** list. In these cases all of stored procedure is executed under	** savepoint for open cursor.	*/	if (((temp = node->nod_arg [e_rse_streams]) 			&& (temp->nod_type == nod_union) 			&& temp->nod_arg [e_rse_reduced]) ||                node->nod_arg [e_rse_sort] ||		node->nod_arg [e_rse_reduced])            request->req_flags &= ~REQ_no_batch;	break;    case nod_trans:	request->req_type = REQ_START_TRANS;	return input;    case nod_update:	node = pass1_update (request, input);	if (request->req_error_handlers)	    {	    temp = MAKE_node (nod_list, 3);	    temp->nod_arg [0] = MAKE_node (nod_start_savepoint, 0);	    temp->nod_arg [1] = node;	    temp->nod_arg [2] = MAKE_node (nod_end_savepoint, 0);	    node = temp;	    }	break;    case nod_while:	node = MAKE_node (input->nod_type, input->nod_count);	node->nod_arg [e_while_cond] = PASS1_node (request,				   input->nod_arg [e_while_cond], proc_flag);	/* CVC: loop numbers should be incremented before analyzing the body	to preserve nesting <==> increasing level number. */	node->nod_arg [e_while_number] = (NOD) request->req_loop_number++;	node->nod_arg [e_while_action] = PASS1_statement (request,				   input->nod_arg [e_while_action], proc_flag);	break;    case nod_abort:    case nod_exception:    case nod_sqlcode:    case nod_gdscode:	return input;    case nod_null:	return NULL;    case nod_set_generator:        node = MAKE_node (input->nod_type, e_gen_id_count);        node->nod_arg [e_gen_id_value] =                PASS1_node (request, input->nod_arg [e_gen_id_value],proc_flag);        node->nod_arg [e_gen_id_name] = input->nod_arg [e_gen_id_name];        request->req_type = REQ_SET_GENERATOR;        break;    case nod_set_generator2:        node = MAKE_node (input->nod_type, e_gen_id_count);        node->nod_arg [e_gen_id_value] =                PASS1_node (request, input->nod_arg [e_gen_id_value],proc_flag);        node->nod_arg [e_gen_id_name] = input->nod_arg [e_gen_id_name];        request->req_type = REQ_SET_GENERATOR;        break;    case nod_union:	ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -901, 	    gds_arg_gds, gds__dsql_command_err, 	    gds_arg_gds, gds__union_err,    /* union not supported */	    0);	break;    default:	ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -901, 	    gds_arg_gds, gds__dsql_command_err, 	    gds_arg_gds, gds__dsql_construct_err, /* Unsupported DSQL construct */	    0);	break;    }/* Finish off by cleaning up contexts */while (request->req_context != base)    LLS_POP (&request->req_context);#ifdef DEV_BUILDif (DSQL_debug > 1)    DSQL_pretty (node, 0);#endifreturn node;} static BOOLEAN aggregate_found (    REQ		request,    NOD		sub,    NOD		*proj){/************************************** * *	a g g r e g a t e _ f o u n d * ************************************** * * Functional description *	Check for an aggregate expression in an  *	rse select list.  It could be buried in  *	an expression tree. * **************************************/BOOLEAN	aggregate, field;DEV_BLKCHK (request, type_req);DEV_BLKCHK (sub, type_nod);field = FALSE;aggregate = aggregate_found2 (request, sub, proj, &field);if (field && aggregate)    ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, 	gds_arg_gds, gds__field_aggregate_err,  /* field used with aggregate */	0);return aggregate;}static BOOLEAN aggregate_found2 (    REQ		request,    NOD		sub,    NOD		*proj,    BOOLEAN	*field){/************************************** * *	a g g r e g a t e _ f o u n d 2 * ************************************** * * Functional description *	Check for an aggregate expression in an  *	rse select list.  It could be buried in  *	an expression tree. * *	field is true if a non-aggregate field reference is seen. * **************************************/BOOLEAN	aggregate;NOD	*ptr, *end;DEV_BLKCHK (request, type_req);DEV_BLKCHK (sub, type_nod);switch (sub->nod_type)    {    /* handle the simple case of a straightforward aggregate */    case nod_agg_average:    case nod_agg_average2:    case nod_agg_total2:    case nod_agg_max:    case nod_agg_min:    case nod_agg_total:    case nod_agg_count:	if ((sub->nod_flags & NOD_AGG_DISTINCT) &&                 (request->req_dbb->dbb_flags & DBB_v3))	    {            /* NOTE: leave the v3 behaviour intact, even though it  */            /* is incorrect in most cases!                          */    	    /* this aggregate requires a projection to be generated */	    *proj = PASS1_node (request, sub->nod_arg [0], 0);	    }	return TRUE;    case nod_field:	*field = TRUE;	return FALSE;    case nod_constant:	return FALSE;    /* for expressions in which an aggregate might       be buried, recursively check for one */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -