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

📄 fastpath.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (IsAbortedTransactionBlockState())		ereport(ERROR,				(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),				 errmsg("current transaction is aborted, "						"commands ignored until end of transaction block")));	/*	 * Begin parsing the buffer contents.	 */	if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)		(void) pq_getmsgstring(msgBuf); /* dummy string */	fid = (Oid) pq_getmsgint(msgBuf, 4);		/* function oid */	/*	 * There used to be a lame attempt at caching lookup info here. Now we	 * just do the lookups on every call.	 */	fip = &my_fp;	fetch_fp_info(fid, fip);	/*	 * Check permission to access and call function.  Since we didn't go	 * through a normal name lookup, we need to check schema usage too.	 */	aclresult = pg_namespace_aclcheck(fip->namespace, GetUserId(), ACL_USAGE);	if (aclresult != ACLCHECK_OK)		aclcheck_error(aclresult, ACL_KIND_NAMESPACE,					   get_namespace_name(fip->namespace));	aclresult = pg_proc_aclcheck(fid, GetUserId(), ACL_EXECUTE);	if (aclresult != ACLCHECK_OK)		aclcheck_error(aclresult, ACL_KIND_PROC,					   get_func_name(fid));	/*	 * Prepare function call info block and insert arguments.	 */	InitFunctionCallInfoData(fcinfo, &fip->flinfo, 0, NULL, NULL);	if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)		rformat = parse_fcall_arguments(msgBuf, fip, &fcinfo);	else		rformat = parse_fcall_arguments_20(msgBuf, fip, &fcinfo);	/* Verify we reached the end of the message where expected. */	pq_getmsgend(msgBuf);	/*	 * If func is strict, must not call it for null args.	 */	callit = true;	if (fip->flinfo.fn_strict)	{		int			i;		for (i = 0; i < fcinfo.nargs; i++)		{			if (fcinfo.argnull[i])			{				callit = false;				break;			}		}	}	if (callit)	{		/* Okay, do it ... */		retval = FunctionCallInvoke(&fcinfo);	}	else	{		fcinfo.isnull = true;		retval = (Datum) 0;	}	SendFunctionResult(retval, fcinfo.isnull, fip->rettype, rformat);	return 0;}/* * Parse function arguments in a 3.0 protocol message * * Argument values are loaded into *fcinfo, and the desired result format * is returned. */static int16parse_fcall_arguments(StringInfo msgBuf, struct fp_info * fip,					  FunctionCallInfo fcinfo){	int			nargs;	int			i;	int			numAFormats;	int16	   *aformats = NULL;	StringInfoData abuf;	/* Get the argument format codes */	numAFormats = pq_getmsgint(msgBuf, 2);	if (numAFormats > 0)	{		aformats = (int16 *) palloc(numAFormats * sizeof(int16));		for (i = 0; i < numAFormats; i++)			aformats[i] = pq_getmsgint(msgBuf, 2);	}	nargs = pq_getmsgint(msgBuf, 2);	/* # of arguments */	if (fip->flinfo.fn_nargs != nargs || nargs > FUNC_MAX_ARGS)		ereport(ERROR,				(errcode(ERRCODE_PROTOCOL_VIOLATION),				 errmsg("function call message contains %d arguments but function requires %d",						nargs, fip->flinfo.fn_nargs)));	fcinfo->nargs = nargs;	if (numAFormats > 1 && numAFormats != nargs)		ereport(ERROR,				(errcode(ERRCODE_PROTOCOL_VIOLATION),				 errmsg("function call message contains %d argument formats but %d arguments",						numAFormats, nargs)));	initStringInfo(&abuf);	/*	 * Copy supplied arguments into arg vector.	 */	for (i = 0; i < nargs; ++i)	{		int			argsize;		int16		aformat;		argsize = pq_getmsgint(msgBuf, 4);		if (argsize == -1)		{			fcinfo->argnull[i] = true;			continue;		}		fcinfo->argnull[i] = false;		if (argsize < 0)			ereport(ERROR,					(errcode(ERRCODE_PROTOCOL_VIOLATION),				  errmsg("invalid argument size %d in function call message",						 argsize)));		/* Reset abuf to empty, and insert raw data into it */		abuf.len = 0;		abuf.data[0] = '\0';		abuf.cursor = 0;		appendBinaryStringInfo(&abuf,							   pq_getmsgbytes(msgBuf, argsize),							   argsize);		if (numAFormats > 1)			aformat = aformats[i];		else if (numAFormats > 0)			aformat = aformats[0];		else			aformat = 0;		/* default = text */		if (aformat == 0)		{			Oid			typinput;			Oid			typioparam;			char	   *pstring;			getTypeInputInfo(fip->argtypes[i], &typinput, &typioparam);			/*			 * Since stringinfo.c keeps a trailing null in place even for			 * binary data, the contents of abuf are a valid C string.	We			 * have to do encoding conversion before calling the typinput			 * routine, though.			 */			pstring = pg_client_to_server(abuf.data, argsize);			fcinfo->arg[i] =				OidFunctionCall3(typinput,								 CStringGetDatum(pstring),								 ObjectIdGetDatum(typioparam),								 Int32GetDatum(-1));			/* Free result of encoding conversion, if any */			if (pstring != abuf.data)				pfree(pstring);		}		else if (aformat == 1)		{			Oid			typreceive;			Oid			typioparam;			/* Call the argument type's binary input converter */			getTypeBinaryInputInfo(fip->argtypes[i], &typreceive, &typioparam);			fcinfo->arg[i] = OidFunctionCall3(typreceive,											  PointerGetDatum(&abuf),											  ObjectIdGetDatum(typioparam),											  Int32GetDatum(-1));			/* Trouble if it didn't eat the whole buffer */			if (abuf.cursor != abuf.len)				ereport(ERROR,						(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),				errmsg("incorrect binary data format in function argument %d",					   i + 1)));		}		else			ereport(ERROR,					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),					 errmsg("unsupported format code: %d", aformat)));	}	/* Return result format code */	return (int16) pq_getmsgint(msgBuf, 2);}/* * Parse function arguments in a 2.0 protocol message * * Argument values are loaded into *fcinfo, and the desired result format * is returned. */static int16parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info * fip,						 FunctionCallInfo fcinfo){	int			nargs;	int			i;	StringInfoData abuf;	nargs = pq_getmsgint(msgBuf, 4);	/* # of arguments */	if (fip->flinfo.fn_nargs != nargs || nargs > FUNC_MAX_ARGS)		ereport(ERROR,				(errcode(ERRCODE_PROTOCOL_VIOLATION),				 errmsg("function call message contains %d arguments but function requires %d",						nargs, fip->flinfo.fn_nargs)));	fcinfo->nargs = nargs;	initStringInfo(&abuf);	/*	 * Copy supplied arguments into arg vector.  In protocol 2.0 these are	 * always assumed to be supplied in binary format.	 *	 * Note: although the original protocol 2.0 code did not have any way for	 * the frontend to specify a NULL argument, we now choose to interpret	 * length == -1 as meaning a NULL.	 */	for (i = 0; i < nargs; ++i)	{		int			argsize;		Oid			typreceive;		Oid			typioparam;		argsize = pq_getmsgint(msgBuf, 4);		if (argsize == -1)		{			fcinfo->argnull[i] = true;			continue;		}		fcinfo->argnull[i] = false;		if (argsize < 0)			ereport(ERROR,					(errcode(ERRCODE_PROTOCOL_VIOLATION),				  errmsg("invalid argument size %d in function call message",						 argsize)));		/* Reset abuf to empty, and insert raw data into it */		abuf.len = 0;		abuf.data[0] = '\0';		abuf.cursor = 0;		appendBinaryStringInfo(&abuf,							   pq_getmsgbytes(msgBuf, argsize),							   argsize);		/* Call the argument type's binary input converter */		getTypeBinaryInputInfo(fip->argtypes[i], &typreceive, &typioparam);		fcinfo->arg[i] = OidFunctionCall3(typreceive,										  PointerGetDatum(&abuf),										  ObjectIdGetDatum(typioparam),										  Int32GetDatum(-1));		/* Trouble if it didn't eat the whole buffer */		if (abuf.cursor != abuf.len)			ereport(ERROR,					(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),			   errmsg("incorrect binary data format in function argument %d",					  i + 1)));	}	/* Desired result format is always binary in protocol 2.0 */	return 1;}

⌨️ 快捷键说明

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