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

📄 plpython.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
		}	}	if (rv < 0)	{		PLy_exception_set(PLy_exc_spi_error,						  "SPI_execute_plan failed: %s",						  SPI_result_code_string(rv));		return NULL;	}	return PLy_spi_execute_fetch_result(SPI_tuptable, SPI_processed, rv);}static PyObject *PLy_spi_execute_query(char *query, long limit){	int			rv;	MemoryContext oldcontext;	oldcontext = CurrentMemoryContext;	PG_TRY();	{		rv = SPI_execute(query, PLy_curr_procedure->fn_readonly, limit);	}	PG_CATCH();	{		MemoryContextSwitchTo(oldcontext);		PLy_error_in_progress = CopyErrorData();		FlushErrorState();		if (!PyErr_Occurred())			PyErr_SetString(PLy_exc_spi_error,							"Unknown error in PLy_spi_execute_query");		/* XXX this oughta be replaced with errcontext mechanism */		PLy_elog(WARNING, "in function %s:",				 PLy_procedure_name(PLy_curr_procedure));		return NULL;	}	PG_END_TRY();	if (rv < 0)	{		PLy_exception_set(PLy_exc_spi_error,						  "SPI_execute failed: %s",						  SPI_result_code_string(rv));		return NULL;	}	return PLy_spi_execute_fetch_result(SPI_tuptable, SPI_processed, rv);}static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status){	PLyResultObject *result;	MemoryContext oldcontext;	result = (PLyResultObject *) PLy_result_new();	Py_DECREF(result->status);	result->status = PyInt_FromLong(status);	if (status == SPI_OK_UTILITY)	{		Py_DECREF(result->nrows);		result->nrows = PyInt_FromLong(0);	}	else if (status != SPI_OK_SELECT)	{		Py_DECREF(result->nrows);		result->nrows = PyInt_FromLong(rows);	}	else	{		PLyTypeInfo args;		int			i;		PLy_typeinfo_init(&args);		Py_DECREF(result->nrows);		result->nrows = PyInt_FromLong(rows);		oldcontext = CurrentMemoryContext;		PG_TRY();		{			if (rows)			{				Py_DECREF(result->rows);				result->rows = PyList_New(rows);				PLy_input_tuple_funcs(&args, tuptable->tupdesc);				for (i = 0; i < rows; i++)				{					PyObject   *row = PLyDict_FromTuple(&args, tuptable->vals[i],														tuptable->tupdesc);					PyList_SetItem(result->rows, i, row);				}				PLy_typeinfo_dealloc(&args);				SPI_freetuptable(tuptable);			}		}		PG_CATCH();		{			MemoryContextSwitchTo(oldcontext);			PLy_error_in_progress = CopyErrorData();			FlushErrorState();			if (!PyErr_Occurred())				PyErr_SetString(PLy_exc_error,							"Unknown error in PLy_spi_execute_fetch_result");			Py_DECREF(result);			PLy_typeinfo_dealloc(&args);			return NULL;		}		PG_END_TRY();	}	return (PyObject *) result;}/* * language handler and interpreter initialization *//* * plpython_init()			- Initialize everything that can be *							  safely initialized during postmaster *							  startup. * * DO NOT make this static --- it has to be callable by preload */voidplpython_init(void){	static volatile int init_active = 0;	/* Do initialization only once */	if (!PLy_first_call)		return;	if (init_active)		elog(FATAL, "initialization of language module failed");	init_active = 1;	Py_Initialize();	PLy_init_interp();	PLy_init_plpy();	if (PyErr_Occurred())		PLy_elog(FATAL, "untrapped error in initialization");	PLy_procedure_cache = PyDict_New();	if (PLy_procedure_cache == NULL)		PLy_elog(ERROR, "could not create procedure cache");	PLy_first_call = 0;}static voidPLy_init_all(void){	/* Execute postmaster-startup safe initialization */	if (PLy_first_call)		plpython_init();	/*	 * Any other initialization that must be done each time a new backend	 * starts -- currently none	 */}static voidPLy_init_interp(void){	PyObject   *mainmod;	mainmod = PyImport_AddModule("__main__");	if ((mainmod == NULL) || (PyErr_Occurred()))		PLy_elog(ERROR, "could not import \"__main__\" module.");	Py_INCREF(mainmod);	PLy_interp_globals = PyModule_GetDict(mainmod);	PLy_interp_safe_globals = PyDict_New();	PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals);	Py_DECREF(mainmod);	if ((PLy_interp_globals == NULL) || (PyErr_Occurred()))		PLy_elog(ERROR, "could not initialize globals");}static voidPLy_init_plpy(void){	PyObject   *main_mod,			   *main_dict,			   *plpy_mod;	PyObject   *plpy,			   *plpy_dict;	/*	 * initialize plpy module	 */	PLy_PlanType.ob_type = PLy_ResultType.ob_type = &PyType_Type;	plpy = Py_InitModule("plpy", PLy_methods);	plpy_dict = PyModule_GetDict(plpy);	/* PyDict_SetItemString(plpy, "PlanType", (PyObject *) &PLy_PlanType); */	PLy_exc_error = PyErr_NewException("plpy.Error", NULL, NULL);	PLy_exc_fatal = PyErr_NewException("plpy.Fatal", NULL, NULL);	PLy_exc_spi_error = PyErr_NewException("plpy.SPIError", NULL, NULL);	PyDict_SetItemString(plpy_dict, "Error", PLy_exc_error);	PyDict_SetItemString(plpy_dict, "Fatal", PLy_exc_fatal);	PyDict_SetItemString(plpy_dict, "SPIError", PLy_exc_spi_error);	/*	 * initialize main module, and add plpy	 */	main_mod = PyImport_AddModule("__main__");	main_dict = PyModule_GetDict(main_mod);	plpy_mod = PyImport_AddModule("plpy");	PyDict_SetItemString(main_dict, "plpy", plpy_mod);	if (PyErr_Occurred())		elog(ERROR, "could not init plpy");}/* the python interface to the elog function * don't confuse these with PLy_elog */static PyObject *PLy_output(int, PyObject *, PyObject *);static PyObject *PLy_debug(PyObject * self, PyObject * args){	return PLy_output(DEBUG2, self, args);}static PyObject *PLy_log(PyObject * self, PyObject * args){	return PLy_output(LOG, self, args);}static PyObject *PLy_info(PyObject * self, PyObject * args){	return PLy_output(INFO, self, args);}static PyObject *PLy_notice(PyObject * self, PyObject * args){	return PLy_output(NOTICE, self, args);}static PyObject *PLy_warning(PyObject * self, PyObject * args){	return PLy_output(WARNING, self, args);}static PyObject *PLy_error(PyObject * self, PyObject * args){	return PLy_output(ERROR, self, args);}static PyObject *PLy_fatal(PyObject * self, PyObject * args){	return PLy_output(FATAL, self, args);}static PyObject *PLy_output(volatile int level, PyObject * self, PyObject * args){	PyObject   *so;	char	   *volatile sv;	MemoryContext oldcontext;	so = PyObject_Str(args);	if ((so == NULL) || ((sv = PyString_AsString(so)) == NULL))	{		level = ERROR;		sv = "Unable to parse error message in `plpy.elog'";	}	oldcontext = CurrentMemoryContext;	PG_TRY();	{		elog(level, "%s", sv);	}	PG_CATCH();	{		MemoryContextSwitchTo(oldcontext);		PLy_error_in_progress = CopyErrorData();		FlushErrorState();		Py_XDECREF(so);		/*		 * returning NULL here causes the python interpreter to bail. when		 * control passes back to PLy_procedure_call, we check for PG		 * exceptions and re-throw the error.		 */		PyErr_SetString(PLy_exc_error, sv);		return NULL;	}	PG_END_TRY();	Py_XDECREF(so);	/*	 * return a legal object so the interpreter will continue on its merry way	 */	Py_INCREF(Py_None);	return Py_None;}/* * Get the last procedure name called by the backend ( the innermost, * If a plpython procedure call calls the backend and the backend calls * another plpython procedure ) * * NB: this returns SQL name, not the internal Python procedure name */static char *PLy_procedure_name(PLyProcedure * proc){	if (proc == NULL)		return "<unknown procedure>";	return proc->proname;}/* output a python traceback/exception via the postgresql elog * function.  not pretty. */static voidPLy_exception_set(PyObject * exc, const char *fmt,...){	char		buf[1024];	va_list		ap;	va_start(ap, fmt);	vsnprintf(buf, sizeof(buf), fmt, ap);	va_end(ap);	PyErr_SetString(exc, buf);}/* Emit a PG error or notice, together with any available info about the * current Python error.  This should be used to propagate Python errors * into PG. */static voidPLy_elog(int elevel, const char *fmt,...){	va_list		ap;	char	   *xmsg,			   *emsg;	int			xlevel;	xmsg = PLy_traceback(&xlevel);	va_start(ap, fmt);	emsg = PLy_vprintf(fmt, ap);	va_end(ap);	PG_TRY();	{		ereport(elevel,				(errmsg("plpython: %s", emsg),				 (xmsg) ? errdetail("%s", xmsg) : 0));	}	PG_CATCH();	{		PLy_free(emsg);		if (xmsg)			PLy_free(xmsg);		PG_RE_THROW();	}	PG_END_TRY();	PLy_free(emsg);	if (xmsg)		PLy_free(xmsg);}static char *PLy_traceback(int *xlevel){	PyObject   *e,			   *v,			   *tb;	PyObject   *eob,			   *vob = NULL;	char	   *vstr,			   *estr,			   *xstr = NULL;	/*	 * get the current exception	 */	PyErr_Fetch(&e, &v, &tb);	/*	 * oops, no exception, return	 */	if (e == NULL)	{		*xlevel = WARNING;		return NULL;	}	PyErr_NormalizeException(&e, &v, &tb);	Py_XDECREF(tb);	eob = PyObject_Str(e);	if ((v) && ((vob = PyObject_Str(v)) != NULL))		vstr = PyString_AsString(vob);	else		vstr = "Unknown";	/*	 * I'm not sure what to do if eob is NULL here -- we can't call PLy_elog	 * because that function calls us, so we could end up with infinite	 * recursion.  I'm not even sure if eob could be NULL here -- would an	 * Assert() be more appropriate?	 */	estr = eob ? PyString_AsString(eob) : "Unknown Exception";	xstr = PLy_printf("%s: %s", estr, vstr);	Py_DECREF(eob);	Py_XDECREF(vob);	Py_XDECREF(v);	/*	 * intuit an appropriate error level based on the exception type	 */	if ((PLy_exc_error) && (PyErr_GivenExceptionMatches(e, PLy_exc_error)))		*xlevel = ERROR;	else if ((PLy_exc_fatal) && (PyErr_GivenExceptionMatches(e, PLy_exc_fatal)))		*xlevel = FATAL;	else		*xlevel = ERROR;	Py_DECREF(e);	return xstr;}static char *PLy_printf(const char *fmt,...){	va_list		ap;	char	   *emsg;	va_start(ap, fmt);	emsg = PLy_vprintf(fmt, ap);	va_end(ap);	return emsg;}static char *PLy_vprintf(const char *fmt, va_list ap){	size_t		blen;	int			bchar,				tries = 2;	char	   *buf;	blen = strlen(fmt) * 2;	if (blen < 256)		blen = 256;	buf = PLy_malloc(blen * sizeof(char));	while (1)	{		bchar = vsnprintf(buf, blen, fmt, ap);		if ((bchar > 0) && (bchar < blen))			return buf;		if (tries-- <= 0)			break;		if (blen > 0)			blen = bchar + 1;		else			blen *= 2;		buf = PLy_realloc(buf, blen);	}	PLy_free(buf);	return NULL;}/* python module code *//* some dumb utility functions */static void *PLy_malloc(size_t bytes){	void	   *ptr = malloc(bytes);	if (ptr == NULL)		ereport(FATAL,				(errcode(ERRCODE_OUT_OF_MEMORY),				 errmsg("out of memory")));	return ptr;}static void *PLy_realloc(void *optr, size_t bytes){	void	   *nptr = realloc(optr, bytes);	if (nptr == NULL)		ereport(FATAL,				(errcode(ERRCODE_OUT_OF_MEMORY),				 errmsg("out of memory")));	return nptr;}/* define this away */static voidPLy_free(void *ptr){	free(ptr);}

⌨️ 快捷键说明

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