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

📄 plpython.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * arguments.	 */	proc->nargs = fcinfo->nargs;	for (i = 0; i < fcinfo->nargs; i++)	{		HeapTuple	argTypeTup;		Form_pg_type argTypeStruct;		argTypeTup = SearchSysCache(TYPEOID,							ObjectIdGetDatum(procStruct->proargtypes[i]),									0, 0, 0);		if (!HeapTupleIsValid(argTypeTup))			elog(ERROR, "cache lookup failed for type %u",				 procStruct->proargtypes[i]);		argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);		if (argTypeStruct->typrelid == InvalidOid)			PLy_input_datum_func(&(proc->args[i]),								 procStruct->proargtypes[i],								 argTypeStruct);		else		{			TupleTableSlot *slot = (TupleTableSlot *) fcinfo->arg[i];			PLy_input_tuple_funcs(&(proc->args[i]),								  slot->ttc_tupleDescriptor);		}		ReleaseSysCache(argTypeTup);	}	/*	 * get the text of the function.	 */	procDatum = DirectFunctionCall1(textout,									PointerGetDatum(&procStruct->prosrc));	procSource = DatumGetCString(procDatum);	PLy_procedure_compile(proc, procSource);	pfree(procSource);	proc->me = PyCObject_FromVoidPtr(proc, NULL);	PyDict_SetItemString(PLy_procedure_cache, key, proc->me);	RESTORE_EXC();	return proc;}voidPLy_procedure_compile(PLyProcedure * proc, const char *src){	PyObject   *crv = NULL;	char	   *msrc;	enter();	proc->globals = PyDict_Copy(PLy_interp_globals);	/*	 * SD is private preserved data between calls GD is global data shared	 * by all functions	 */	proc->statics = PyDict_New();	PyDict_SetItemString(proc->globals, "SD", proc->statics);	/*	 * insert the function code into the interpreter	 */	msrc = PLy_procedure_munge_source(proc->pyname, src);	crv = PyRun_String(msrc, Py_file_input, proc->globals, NULL);	free(msrc);	if ((crv != NULL) && (!PyErr_Occurred()))	{		int			clen;		char		call[NAMEDATALEN + 256];		Py_DECREF(crv);		/*		 * compile a call to the function		 */		clen = snprintf(call, sizeof(call), "%s()", proc->pyname);		if ((clen < 0) || (clen >= sizeof(call)))			elog(ERROR, "string would overflow buffer");		proc->code = Py_CompileString(call, "<string>", Py_eval_input);		if ((proc->code != NULL) && (!PyErr_Occurred()))			return;	}	else		Py_XDECREF(crv);	PLy_elog(ERROR, "could not compile function \"%s\"", proc->proname);}char *PLy_procedure_munge_source(const char *name, const char *src){	char	   *mrc,			   *mp;	const char *sp;	size_t		mlen,				plen;	enter();	/*	 * room for function source and the def statement	 */	mlen = (strlen(src) * 2) + strlen(name) + 16;	mrc = PLy_malloc(mlen);	plen = snprintf(mrc, mlen, "def %s():\n\t", name);	Assert(plen >= 0 && plen < mlen);	sp = src;	mp = mrc + plen;	while (*sp != '\0')	{		if (*sp == '\n')		{			*mp++ = *sp++;			*mp++ = '\t';		}		else			*mp++ = *sp++;	}	*mp++ = '\n';	*mp++ = '\n';	*mp = '\0';	if (mp > (mrc + mlen))		elog(FATAL, "buffer overrun in PLy_munge_source");	return mrc;}voidPLy_procedure_delete(PLyProcedure * proc){	int			i;	enter();	Py_XDECREF(proc->code);	Py_XDECREF(proc->statics);	Py_XDECREF(proc->globals);	Py_XDECREF(proc->me);	if (proc->proname)		PLy_free(proc->proname);	if (proc->pyname)		PLy_free(proc->pyname);	for (i = 0; i < proc->nargs; i++)		if (proc->args[i].is_rel == 1)		{			if (proc->args[i].in.r.atts)				PLy_free(proc->args[i].in.r.atts);			if (proc->args[i].out.r.atts)				PLy_free(proc->args[i].out.r.atts);		}	leave();}/* conversion functions.  remember output from python is * input to postgresql, and vis versa. */voidPLy_input_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc){	int			i;	enter();	if (arg->is_rel == 0)		elog(ERROR, "PLyTypeInfo struct is initialized for a Datum");	arg->is_rel = 1;	arg->in.r.natts = desc->natts;	arg->in.r.atts = malloc(desc->natts * sizeof(PLyDatumToOb));	for (i = 0; i < desc->natts; i++)	{		HeapTuple	typeTup;		Form_pg_type typeStruct;		if (desc->attrs[i]->attisdropped)			continue;		typeTup = SearchSysCache(TYPEOID,							  ObjectIdGetDatum(desc->attrs[i]->atttypid),								 0, 0, 0);		if (!HeapTupleIsValid(typeTup))			elog(ERROR, "cache lookup failed for type %u",				 desc->attrs[i]->atttypid);		typeStruct = (Form_pg_type) GETSTRUCT(typeTup);		PLy_input_datum_func2(&(arg->in.r.atts[i]),							  desc->attrs[i]->atttypid,							  typeStruct);		ReleaseSysCache(typeTup);	}}voidPLy_output_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc){	int			i;	enter();	if (arg->is_rel == 0)		elog(ERROR, "PLyTypeInfo struct is initialized for a Datum");	arg->is_rel = 1;	arg->out.r.natts = desc->natts;	arg->out.r.atts = malloc(desc->natts * sizeof(PLyDatumToOb));	for (i = 0; i < desc->natts; i++)	{		HeapTuple	typeTup;		Form_pg_type typeStruct;		if (desc->attrs[i]->attisdropped)			continue;		typeTup = SearchSysCache(TYPEOID,							  ObjectIdGetDatum(desc->attrs[i]->atttypid),								 0, 0, 0);		if (!HeapTupleIsValid(typeTup))			elog(ERROR, "cache lookup failed for type %u",				 desc->attrs[i]->atttypid);		typeStruct = (Form_pg_type) GETSTRUCT(typeTup);		PLy_output_datum_func2(&(arg->out.r.atts[i]), typeStruct);		ReleaseSysCache(typeTup);	}}voidPLy_output_datum_func(PLyTypeInfo * arg, Form_pg_type typeStruct){	enter();	if (arg->is_rel == 1)		elog(ERROR, "PLyTypeInfo struct is initialized for a Tuple");	arg->is_rel = 0;	PLy_output_datum_func2(&(arg->out.d), typeStruct);}voidPLy_output_datum_func2(PLyObToDatum * arg, Form_pg_type typeStruct){	enter();	perm_fmgr_info(typeStruct->typinput, &arg->typfunc);	arg->typelem = typeStruct->typelem;	arg->typbyval = typeStruct->typbyval;}voidPLy_input_datum_func(PLyTypeInfo * arg, Oid typeOid, Form_pg_type typeStruct){	enter();	if (arg->is_rel == 1)		elog(ERROR, "PLyTypeInfo struct is initialized for Tuple");	arg->is_rel = 0;	PLy_input_datum_func2(&(arg->in.d), typeOid, typeStruct);}voidPLy_input_datum_func2(PLyDatumToOb * arg, Oid typeOid, Form_pg_type typeStruct){	/* Get the type's conversion information */	perm_fmgr_info(typeStruct->typoutput, &arg->typfunc);	arg->typelem = typeStruct->typelem;	arg->typbyval = typeStruct->typbyval;	/* Determine which kind of Python object we will convert to */	switch (typeOid)	{		case BOOLOID:			arg->func = PLyBool_FromString;			break;		case FLOAT4OID:		case FLOAT8OID:		case NUMERICOID:			arg->func = PLyFloat_FromString;			break;		case INT2OID:		case INT4OID:			arg->func = PLyInt_FromString;			break;		case INT8OID:			arg->func = PLyLong_FromString;			break;		default:			arg->func = PLyString_FromString;			break;	}}voidPLy_typeinfo_init(PLyTypeInfo * arg){	arg->is_rel = -1;	arg->in.r.natts = arg->out.r.natts = 0;	arg->in.r.atts = NULL;	arg->out.r.atts = NULL;}voidPLy_typeinfo_dealloc(PLyTypeInfo * arg){	if (arg->is_rel == 1)	{		if (arg->in.r.atts)			PLy_free(arg->in.r.atts);		if (arg->out.r.atts)			PLy_free(arg->out.r.atts);	}}/* assumes that a bool is always returned as a 't' or 'f' */PyObject *PLyBool_FromString(const char *src){	enter();	if (src[0] == 't')		return PyInt_FromLong(1);	return PyInt_FromLong(0);}PyObject *PLyFloat_FromString(const char *src){	double		v;	char	   *eptr;	enter();	errno = 0;	v = strtod(src, &eptr);	if ((*eptr != '\0') || (errno))		return NULL;	return PyFloat_FromDouble(v);}PyObject *PLyInt_FromString(const char *src){	long		v;	char	   *eptr;	enter();	errno = 0;	v = strtol(src, &eptr, 0);	if ((*eptr != '\0') || (errno))		return NULL;	return PyInt_FromLong(v);}PyObject *PLyLong_FromString(const char *src){	return PyLong_FromString((char *) src, NULL, 0);}PyObject *PLyString_FromString(const char *src){	return PyString_FromString(src);}PyObject *PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc){	DECLARE_EXC();	PyObject   *volatile dict;	int			i;	enter();	if (info->is_rel != 1)		elog(ERROR, "PLyTypeInfo structure describes a datum");	dict = PyDict_New();	if (dict == NULL)		PLy_elog(ERROR, "could not create tuple dictionary");	SAVE_EXC();	if (TRAP_EXC())	{		RESTORE_EXC();		Py_DECREF(dict);		RERAISE_EXC();	}	for (i = 0; i < info->in.r.natts; i++)	{		char	   *key,				   *vsrc;		Datum		vattr,					vdat;		bool		is_null;		PyObject   *value;		if (desc->attrs[i]->attisdropped)			continue;		key = NameStr(desc->attrs[i]->attname);		vattr = heap_getattr(tuple, (i + 1), desc, &is_null);		if ((is_null) || (info->in.r.atts[i].func == NULL))			PyDict_SetItemString(dict, key, Py_None);		else		{			vdat = FunctionCall3(&info->in.r.atts[i].typfunc,								 vattr,							ObjectIdGetDatum(info->in.r.atts[i].typelem),							   Int32GetDatum(desc->attrs[i]->atttypmod));			vsrc = DatumGetCString(vdat);			/*			 * no exceptions allowed			 */			value = info->in.r.atts[i].func(vsrc);			pfree(vsrc);			PyDict_SetItemString(dict, key, value);			Py_DECREF(value);		}	}	RESTORE_EXC();	return dict;}/* initialization, some python variables function declared here *//* interface to postgresql elog */static PyObject *PLy_debug(PyObject *, PyObject *);static PyObject *PLy_log(PyObject *, PyObject *);static PyObject *PLy_info(PyObject *, PyObject *);static PyObject *PLy_notice(PyObject *, PyObject *);static PyObject *PLy_warning(PyObject *, PyObject *);static PyObject *PLy_error(PyObject *, PyObject *);static PyObject *PLy_fatal(PyObject *, PyObject *);/* PLyPlanObject, PLyResultObject and SPI interface */#define is_PLyPlanObject(x) ((x)->ob_type == &PLy_PlanType)static PyObject *PLy_plan_new(void);static void PLy_plan_dealloc(PyObject *);static PyObject *PLy_plan_getattr(PyObject *, char *);static PyObject *PLy_plan_status(PyObject *, PyObject *);static PyObject *PLy_result_new(void);static void PLy_result_dealloc(PyObject *);static PyObject *PLy_result_getattr(PyObject *, char *);#ifdef NOT_USED/* Appear to be unused */static PyObject *PLy_result_fetch(PyObject *, PyObject *);static PyObject *PLy_result_nrows(PyObject *, PyObject *);static PyObject *PLy_result_status(PyObject *, PyObject *);#endifstatic int	PLy_result_length(PyObject *);static PyObject *PLy_result_item(PyObject *, int);static PyObject *PLy_result_slice(PyObject *, int, int);static int	PLy_result_ass_item(PyObject *, int, PyObject *);static int	PLy_result_ass_slice(PyObject *, int, int, PyObject *);static PyObject *PLy_spi_prepare(PyObject *, PyObject *);static PyObject *PLy_spi_execute(PyObject *, PyObject *);static const char *PLy_spi_error_string(int);static PyObject *PLy_spi_execute_query(char *query, int limit);static PyObject *PLy_spi_execute_plan(PyObject *, PyObject *, int);static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *, int, int);static PyTypeObject PLy_PlanType = {	PyObject_HEAD_INIT(NULL)	0,							/* ob_size */	"PLyPlan",					/* tp_name */	sizeof(PLyPlanObject),		/* tp_size */	0,							/* tp_itemsize */	/*	 * methods	 */	(destructor) PLy_plan_dealloc,		/* tp_dealloc */	0,							/* tp_print */	(getattrfunc) PLy_plan_getattr,		/* tp_getattr */	0,							/* tp_setattr */	0,							/* tp_compare */	0,							/* tp_repr */	0,							/* tp_as_number */	0,							/* tp_as_sequence */	0,							/* tp_as_mapping */	0,							/* tp_hash */	0,							/* tp_call */	0,							/* tp_str */	0,							/* tp_getattro */	0,							/* tp_setattro */	0,							/* tp_as_buffer */	0,							/* tp_xxx4 */	PLy_plan_doc,				/* tp_doc */};static PyMethodDef PLy_plan_methods[] = {	{"status", (PyCFunction) PLy_plan_status, METH_VARARGS, NULL},	{NULL, NULL, 0, NULL}};static PySequenceMethods PLy_result_as_sequence = {	(inquiry) PLy_result_length,	/* sq_length */	(binaryfunc) 0,				/* sq_concat */	(intargfunc) 0,				/* sq_repeat */	(intargfunc) PLy_result_item,		/* sq_item */	(intintargfunc) PLy_result_slice,	/* sq_slice */	(intobjargproc) PLy_result_ass_item,		/* sq_ass_item */	(intintobjargproc) PLy_result_ass_slice,	/* sq_ass_slice */};static PyTypeObject PLy_ResultType = {	PyObject_HEAD_INIT(NULL)	0,							/* ob_size */	"PLyResult",				/* tp_name */	sizeof(PLyResultObject),	/* tp_size */	0,							/* tp_itemsize */	/*	 * methods	 */	(destructor) PLy_result_dealloc,	/* tp_dealloc */	0,							/* tp_print */	(getattrfunc) PLy_result_getattr,	/* tp_getattr */	0,							/* tp_setattr */	0,							/* tp_compare */	0,							/* tp_repr */	0,							/* tp_as_number */	&PLy_result_as_sequence,	/* tp_as_sequence */	0,							/* tp_as_mapping */	0,							/* tp_hash */

⌨️ 快捷键说明

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