📄 plpython.c
字号:
PLy_exception_set(PLy_exc_spi_error, "Unable to execute query. SPI_exec failed -- %s", PLy_spi_error_string(rv)); return NULL; } return PLy_spi_execute_fetch_result(SPI_tuptable, SPI_processed, rv);}PyObject *PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status){ PLyResultObject *result; enter(); 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 { DECLARE_EXC(); PLyTypeInfo args; int i; PLy_typeinfo_init(&args); Py_DECREF(result->nrows); result->nrows = PyInt_FromLong(rows); SAVE_EXC(); if (TRAP_EXC()) { RESTORE_EXC(); if (!PyErr_Occurred()) PyErr_SetString(PLy_exc_error, "Unknown error in PLy_spi_execute_fetch_result"); Py_DECREF(result); PLy_typeinfo_dealloc(&args); RERAISE_EXC(); } 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); } RESTORE_EXC(); } return (PyObject *) result;}const char *PLy_spi_error_string(int code){ switch (code) { case SPI_ERROR_TYPUNKNOWN: return "SPI_ERROR_TYPUNKNOWN"; case SPI_ERROR_NOOUTFUNC: return "SPI_ERROR_NOOUTFUNC"; case SPI_ERROR_NOATTRIBUTE: return "SPI_ERROR_NOATTRIBUTE"; case SPI_ERROR_TRANSACTION: return "SPI_ERROR_TRANSACTION"; case SPI_ERROR_PARAM: return "SPI_ERROR_PARAM"; case SPI_ERROR_ARGUMENT: return "SPI_ERROR_ARGUMENT"; case SPI_ERROR_CURSOR: return "SPI_ERROR_CURSOR"; case SPI_ERROR_UNCONNECTED: return "SPI_ERROR_UNCONNECTED"; case SPI_ERROR_OPUNKNOWN: return "SPI_ERROR_OPUNKNOWN"; case SPI_ERROR_COPY: return "SPI_ERROR_COPY"; case SPI_ERROR_CONNECT: return "SPI_ERROR_CONNECT"; } return "Unknown or Invalid code";}/* 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; enter(); 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; leave();}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 */}voidPLy_init_interp(void){ PyObject *mainmod; enter(); 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");}voidPLy_init_plpy(void){ PyObject *main_mod, *main_dict, *plpy_mod; PyObject *plpy, *plpy_dict; enter(); /* * 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 *);PyObject *PLy_debug(PyObject * self, PyObject * args){ return PLy_output(DEBUG2, self, args);}PyObject *PLy_log(PyObject * self, PyObject * args){ return PLy_output(LOG, self, args);}PyObject *PLy_info(PyObject * self, PyObject * args){ return PLy_output(INFO, self, args);}PyObject *PLy_notice(PyObject * self, PyObject * args){ return PLy_output(NOTICE, self, args);}PyObject *PLy_warning(PyObject * self, PyObject * args){ return PLy_output(WARNING, self, args);}PyObject *PLy_error(PyObject * self, PyObject * args){ return PLy_output(ERROR, self, args);}PyObject *PLy_fatal(PyObject * self, PyObject * args){ return PLy_output(FATAL, self, args);}PyObject *PLy_output(volatile int level, PyObject * self, PyObject * args){ DECLARE_EXC(); PyObject *so; char *volatile sv; enter(); if (args == NULL) elog(WARNING, "args is NULL"); so = PyObject_Str(args); if ((so == NULL) || ((sv = PyString_AsString(so)) == NULL)) { level = ERROR; sv = "Unable to parse error message in `plpy.elog'"; } /* * returning NULL here causes the python interpreter to bail. when * control passes back into plpython_*_handler, we check for python * exceptions and do the actual elog call. actually PLy_elog. */ if (level == ERROR) { PyErr_SetString(PLy_exc_error, sv); return NULL; } else if (level >= FATAL) { PyErr_SetString(PLy_exc_fatal, sv); return NULL; } /* * ok, this is a WARNING, or LOG message * * but just in case DON'T long jump out of the interpreter! */ SAVE_EXC(); if (TRAP_EXC()) { RESTORE_EXC(); Py_XDECREF(so); /* * the real error message should already be written into the * postgresql log, no? whatever, this shouldn't happen so die * hideously. */ elog(FATAL, "elog threw an unknown exception"); RERAISE_EXC(); } elog(level, "%s", sv); RESTORE_EXC(); Py_XDECREF(so); Py_INCREF(Py_None); /* * return a legal object so the interpreter will continue on its merry * way */ 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 */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 char *PLy_traceback(int *);static char *PLy_vprintf(const char *fmt, va_list ap);static char *PLy_printf(const char *fmt,...);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);}voidPLy_elog(int elevel, const char *fmt,...){ DECLARE_EXC(); va_list ap; char *xmsg, *emsg; int xlevel; enter(); xmsg = PLy_traceback(&xlevel); va_start(ap, fmt); emsg = PLy_vprintf(fmt, ap); va_end(ap); SAVE_EXC(); if (TRAP_EXC()) { RESTORE_EXC(); mark(); /* * elog called siglongjmp. cleanup, restore and reraise */ PLy_restart_in_progress += 1; PLy_free(emsg); if (xmsg) PLy_free(xmsg); RERAISE_EXC(); } ereport(elevel, (errmsg("plpython: %s", emsg), (xmsg) ? errdetail("%s", xmsg) : 0)); PLy_free(emsg); if (xmsg) PLy_free(xmsg); leave(); RESTORE_EXC();}char *PLy_traceback(int *xlevel){ PyObject *e, *v, *tb; PyObject *eob, *vob = NULL; char *vstr, *estr, *xstr = NULL; enter(); /* * 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); eob = PyObject_Str(e); if ((v) && ((vob = PyObject_Str(v)) != NULL)) vstr = PyString_AsString(vob); else vstr = "Unknown"; estr = PyString_AsString(eob); xstr = PLy_printf("%s: %s", estr, vstr); Py_DECREF(eob); Py_XDECREF(vob); /* * intuit an appropriate error level for 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; leave(); return xstr;}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;}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 */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;}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 */voidPLy_free(void *ptr){ free(ptr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -