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

📄 gen.c

📁 firebird源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
if (request->req_flags & REQ_blr_version4)    STUFF (blr_version4);else    STUFF (blr_version5);STUFF (blr_begin);if (request->req_type == REQ_SELECT ||    request->req_type == REQ_SELECT_UPD)    gen_select (request, node);else    {    message = request->req_send;    if (!message->msg_parameter)	request->req_send = NULL;    else	{	GEN_port (request, message);	if (request->req_type != REQ_EXEC_PROCEDURE)	    {	    STUFF (blr_receive);	    STUFF (message->msg_number);	    }	}    message = request->req_receive;    if (!message->msg_parameter)	request->req_receive = NULL;    else	GEN_port (request, message);    GEN_statement (request, node);    }STUFF (blr_end);STUFF (blr_eoc);}void GEN_start_transaction (    REQ		request,    NOD		tran_node){/************************************** * *	G E N _ s t a r t _ t r a n s a c t i o n * ************************************** * * Functional description *	Generate tpb for set transaction.  Use blr string of request. *	If a value is not specified, default is not STUFF'ed, let the *	engine handle it. *	Do not allow an option to be specified more than once. * **************************************/NOD	*temp, ptr, *end;SSHORT	count;NOD	reserve, node;SSHORT	sw_access, sw_wait, sw_isolation, sw_reserve;USHORT	lock_level;count = tran_node->nod_count;if (!count)    return;sw_access = sw_wait = sw_isolation = sw_reserve = 0;node  = tran_node->nod_arg [0];if (!node)    return;/* find out isolation level - if specified. This is required for * specifying the correct lock level in reserving clause. */lock_level = gds__tpb_shared;if (count = node->nod_count)    {    while (count--)	{	ptr = node->nod_arg [count];	if ((!ptr) || (ptr->nod_type != nod_isolation))	    continue;	lock_level = (ptr->nod_flags & NOD_CONSISTENCY) ? gds__tpb_protected : gds__tpb_shared;	}    }/* Stuff some version info. */if (count = node->nod_count)    STUFF (gds__tpb_version1);while (count--)    {    ptr = node->nod_arg [count];    if (!ptr)	continue;    switch (ptr->nod_type)	{	case nod_access:	    if (sw_access)		ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, 		    gds_arg_gds, gds__dsql_dup_option, 		    0);	    sw_access = 1;	    if (ptr->nod_flags & NOD_READ_ONLY)		STUFF (gds__tpb_read);	    else		STUFF (gds__tpb_write);	    break;	    	case nod_wait:	    if (sw_wait)		ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, 		    gds_arg_gds, gds__dsql_dup_option, 		    0);	    sw_wait = 1;	    if (ptr->nod_flags & NOD_NO_WAIT)		STUFF (gds__tpb_nowait);	    else		STUFF (gds__tpb_wait);	    break;	    	case nod_isolation:	    if (sw_isolation)		ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, 		    gds_arg_gds, gds__dsql_dup_option, 		    0);	    sw_isolation = 1;	    if (ptr->nod_flags & NOD_CONCURRENCY)		STUFF (gds__tpb_concurrency);	    else if (ptr->nod_flags & NOD_CONSISTENCY)		STUFF (gds__tpb_consistency);	    else 		{		STUFF (gds__tpb_read_committed);	    		if ((ptr->nod_count) && (ptr->nod_arg [0]) && 		    (ptr->nod_arg [0]->nod_type == nod_version))		    {		    if (ptr->nod_arg [0]->nod_flags & NOD_VERSION)			STUFF (gds__tpb_rec_version);		    else			STUFF (gds__tpb_no_rec_version);		    }		else		    STUFF (gds__tpb_no_rec_version);		}	    break;	    	case nod_reserve:	    if (sw_reserve)		ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, 		    gds_arg_gds, gds__dsql_dup_option, 		    0);	    sw_reserve = 1;	    reserve = ptr->nod_arg [0];	    if (reserve)		for (temp = reserve->nod_arg, end = temp + reserve->nod_count; 					temp < end; temp++)		    gen_table_lock (request, *temp, lock_level);	    break;	default:	    ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, 		gds_arg_gds, gds__dsql_tran_err, 		0);	}    }}void GEN_statement (    REQ		request,    NOD		node){/************************************** * *	G E N _ s t a t e m e n t * ************************************** * * Functional description *	Generate blr for an arbitrary expression. * **************************************/NOD	temp, *ptr, *end;CTX	context;MSG	message;STR	name;STR	string;TEXT	*p;ULONG	id_length; switch (node->nod_type)    {    case nod_assign:	STUFF (blr_assignment);	GEN_expr (request, node->nod_arg [0]);	GEN_expr (request, node->nod_arg [1]);	return;	    case nod_block:	STUFF (blr_block);	GEN_statement (request, node->nod_arg [e_blk_action]);	if (node->nod_count > 1)	    { 	    temp = node->nod_arg [e_blk_errs];	    for (ptr = temp->nod_arg, end = ptr + temp->nod_count;				 ptr < end; ptr++)		GEN_statement (request, *ptr);	    }	STUFF (blr_end);	return;    case nod_erase:	if ((temp = node->nod_arg [e_era_rse]) != NULL)	    {	    STUFF (blr_for);	    GEN_expr (request, temp);	    }	temp = node->nod_arg [e_era_relation];	context = (CTX) temp->nod_arg [e_rel_context];	STUFF (blr_erase);	STUFF (context->ctx_context);	return;    case nod_erase_current:      STUFF (blr_erase);      context = (CTX) node->nod_arg [e_erc_context];      STUFF (context->ctx_context);      return;    case nod_exec_procedure:	if (request->req_type == REQ_EXEC_PROCEDURE)	    {	    if (message = request->req_receive)		{		STUFF (blr_begin);		STUFF (blr_send);		STUFF (message->msg_number);		}	    }	else	    message = NULL;	STUFF (blr_exec_proc);	name = (STR) node->nod_arg [e_exe_procedure];	STUFF_CSTRING (name->str_data);	if (temp = node->nod_arg [e_exe_inputs])	    {	    STUFF_WORD (temp->nod_count);	    for (ptr = temp->nod_arg, end = ptr + temp->nod_count;		 ptr < end; ptr++)		GEN_expr (request, *ptr);	    }	else	    STUFF_WORD (0);	if (temp = node->nod_arg [e_exe_outputs])	    {	    STUFF_WORD (temp->nod_count);	    for (ptr = temp->nod_arg, end = ptr + temp->nod_count;		 ptr < end; ptr++)		GEN_expr (request, *ptr);	    }	else	    STUFF_WORD (0);	if (message)	    STUFF (blr_end);	return;	    case nod_for_select:	gen_for_select (request, node);	return;    case nod_set_generator:    case nod_set_generator2:	STUFF (blr_set_generator);	string = (STR) node->nod_arg [e_gen_id_name];	STUFF_CSTRING (string->str_data);	GEN_expr (request, node->nod_arg [e_gen_id_value]);	return;    case nod_if:	STUFF (blr_if);	GEN_expr (request, node->nod_arg [e_if_condition]);	GEN_statement (request, node->nod_arg [e_if_true]);	if (node->nod_arg [e_if_false])	    GEN_statement (request, node->nod_arg [e_if_false]);	else	    STUFF (blr_end);	return;	    case nod_list:	STUFF (blr_begin);	for (ptr = node->nod_arg, end = ptr + node->nod_count; ptr < end; ptr++)	    GEN_statement (request, *ptr);	STUFF (blr_end);	return;    case nod_modify:	if ((temp = node->nod_arg [e_mod_rse]) != NULL)	    {	    STUFF (blr_for);	    GEN_expr (request, temp);	    }	STUFF (blr_modify);	temp = node->nod_arg [e_mod_source];	context = (CTX) temp->nod_arg [e_rel_context];	STUFF (context->ctx_context);	temp = node->nod_arg [e_mod_update];	context = (CTX) temp->nod_arg [e_rel_context];	STUFF (context->ctx_context);	GEN_statement (request, node->nod_arg [e_mod_statement]);	return;    case nod_modify_current:	STUFF (blr_modify);	context = (CTX) node->nod_arg [e_mdc_context];	STUFF (context->ctx_context);	temp = node->nod_arg [e_mdc_update];	context = (CTX) temp->nod_arg [e_rel_context];	STUFF (context->ctx_context);	GEN_statement (request, node->nod_arg [e_mdc_statement]);	return;    case nod_on_error:	STUFF (blr_error_handler);	temp = node->nod_arg [e_err_errs];	STUFF_WORD (temp->nod_count);	for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++)	    gen_error_condition (request, *ptr);	GEN_statement (request, node->nod_arg [e_err_action]);	return;    case nod_post:	STUFF (blr_post);	GEN_expr (request, node->nod_arg [e_pst_event]);	return;	    case nod_return:	GEN_return (request, node->nod_arg [e_rtn_procedure], FALSE);	return;    case nod_exit:	STUFF (blr_leave);	STUFF (0);	return;    case nod_breakleave:	STUFF (blr_leave);	STUFF ((int) node->nod_arg [e_break_number]);	return;    case nod_exec_sql:	STUFF (blr_exec_sql);	GEN_expr (request, node->nod_arg [e_exec_vc]);	return;		case nod_store:	if ((temp = node->nod_arg [e_sto_rse]) != NULL)	    {	    STUFF (blr_for);	    GEN_expr (request, temp);	    }	STUFF (blr_store);	GEN_expr (request, node->nod_arg [e_sto_relation]);	GEN_statement (request, node->nod_arg [e_sto_statement]);	return;    case nod_abort:	STUFF (blr_leave);	STUFF ((int) node->nod_arg [e_abrt_number]);	return;	    case nod_start_savepoint:	STUFF (blr_start_savepoint);	return;	    case nod_end_savepoint:	STUFF (blr_end_savepoint);	return;	    case nod_exception_stmt:	STUFF (blr_abort);	STUFF (blr_exception);	string = (STR) node->nod_arg [0];	if (!(string->str_flags & STR_delimited_id))	    {	    id_length = string->str_length;	    for (p = string->str_data; *p; id_length--)		{		*p = UPPER (*p);		*p++; 		}	    }	STUFF_CSTRING (string->str_data);	return;	    case nod_while:	STUFF (blr_label);	STUFF ((int) node->nod_arg [e_while_number]);	STUFF (blr_loop);	STUFF (blr_begin);	STUFF (blr_if);	GEN_expr (request, node->nod_arg [e_while_cond]);	GEN_statement (request, node->nod_arg [e_while_action]);	STUFF (blr_leave);	STUFF ((int) node->nod_arg [e_while_number]);	STUFF (blr_end);	return;	    case nod_sqlcode:    case nod_gdscode:	STUFF (blr_abort);	gen_error_condition (request, node);	return;    default:	ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -901, 	    gds_arg_gds, gds__dsql_internal_err, 	    gds_arg_gds, gds__node_err,     /* gen.c: node not supported */	    0);    }}static void gen_aggregate (    REQ		request,    NOD		node){/************************************** * *	g e n _ a g g r e g a t e * ************************************** * * Functional description *	Generate blr for a relation reference. * **************************************/NOD	list, *ptr, *end;CTX	context;context = (CTX) node->nod_arg [e_agg_context];STUFF (blr_aggregate);STUFF (context->ctx_context);gen_rse (request, node->nod_arg [e_agg_rse]);/* Handle GROUP BY clause */STUFF (blr_group_by); if ((list = node->nod_arg [e_agg_group]) != NULL)    {    STUFF (list->nod_count);    for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++)	GEN_expr (request, *ptr);    }else    STUFF (0);/* Generate value map */gen_map (request, context->ctx_map);}static void gen_cast (    REQ		request,    NOD		node){/************************************** * *      g e n _ c a s t * ************************************** * * Functional description *      Generate BLR for a data-type cast operation * **************************************/FLD     field; STUFF (blr_cast);field = (FLD) node->nod_arg [e_cast_target];DDL_put_field_dtype (request, field, TRUE);GEN_expr (request, node->nod_arg [e_cast_source]);}static void gen_constant (    REQ		request,    DSC		*desc,    BOOLEAN      negate_value){/************************************** * *	g e n _ c o n s t a n t * ************************************** * * Functional description *	Generate BLR for a constant. * **************************************/UCHAR	*p;USHORT	l;SLONG	value;SINT64  i64value;DSC	tmp_desc;STUFF (blr_literal);if ((desc->dsc_dtype == dtype_double) && (request->req_dbb->dbb_flags & DBB_v3))    /* v3 doesn't understand blr_double literal, generate blr_text instead */    {    tmp_desc = *desc;    tmp_desc.dsc_dtype = dtype_text;     tmp_desc.dsc_length = desc->dsc_scale;	/* length of string literal */    tmp_desc.dsc_scale = 0;    desc = &tmp_desc;    }l = desc->dsc_length;p = desc->dsc_address;switch (desc->dsc_dtype)    {    case dtype_short:        gen_descriptor (request, desc, TRUE);	value = *(SSHORT*) p;        if (negate_value)	    value = -value;	STUFF_WORD (value);	break;    case dtype_long:        gen_descriptor (request, desc, TRUE);	value = *(SLONG*) p;        if (negate_value)	    value = -value;	STUFF_WORD (value);	STUFF_WORD (value >> 16);	break;    case dtype_sql_time:    case dtype_sql_date:        gen_descriptor (request, desc, TRUE);	value = *(SLONG*) p;	STUFF_WORD (value);	STUFF_WORD (value >> 16);	break;    case dtype_double:        /* this is used for approximate/large numeric literal           which is transmitted to the engine as a string.         */        gen_descriptor (request, desc, TRUE);	l = (USHORT) desc->dsc_scale;		/* length of string literal */        if (negate_value)	    {	    STUFF_WORD(l+1);	    STUFF('-');	    }	else	    {	    STUFF_WORD (l);	    }	        if (l)            do STUFF (*p++); while (--l);        break;     case dtype_int64:       i64value = *(SINT64 *)p;       if (negate_value)	   i64value = -i64value;       else if (i64value == MIN_SINT64)	 {	   /* UH OH!	    * yylex correctly recognized the digits as the most-negative	    * possible INT64 value, but unfortunately, there was no	    * preceding '-' (a fact which the lexer could not know).	    * The value is too big for a positive INT64 value, and it	    * didn't contain an exponent so it's not a valid DOUBLE	    * PRECISION literal either, so we have to bounce it.	    */	   ERRD_post(isc_sqlerr,		     gds_arg_number, (SLONG) -104    , 		     gds_arg_gds   , isc_arith_except,		     0);	 }       /* We and the lexer both agree that this is an SINT64 constant,	* and if the value needed to be negated, it already has been.	* If the value will fit into a 32-bit signed integer, generate	* it that way, else as an INT64.	*/       if ( (i64value >= (SINT64) MIN_SLONG) &&	    (i64value <= (SINT64) MAX_SLONG) )	   {	     STUFF      (blr_long);	     STUFF      (desc->dsc_scale);	     STUFF_WORD (i64value);	     STUFF_WORD (i64value >> 16);	     break;	   }       else	 {	   STUFF      (blr_int64);	   STUFF      (desc->dsc_scale);	   STUFF_WORD (i64value);	   STUFF_WORD (i64value >> 16);	   STUFF_WORD (i64value >> 32);	   STUFF_WORD (i64value >> 48);	 }

⌨️ 快捷键说明

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