void reportException(PyObject *pErrType, PyObject *pErrValue, PyObject *pErrTraceback) { char *errName, *errValue, *errTraceback = ""; PyObject *traceback_list; PyObject *pTemp; PyObject *tracebackModule = PyImport_ImportModule("traceback"); PyObject *format_exception = PyObject_GetAttrString(tracebackModule, "format_exception"); PyObject *newline = PyString_FromString("\n"); int severity; PyErr_NormalizeException(&pErrType, &pErrValue, &pErrTraceback); pTemp = PyObject_GetAttrString(pErrType, "__name__"); errName = PyString_AsString(pTemp); errValue = PyString_AsString(PyObject_Str(pErrValue)); if (pErrTraceback != NULL) { traceback_list = PyObject_CallFunction(format_exception, "(O,O,O)", pErrType, pErrValue, pErrTraceback); errTraceback = PyString_AsString(PyObject_CallMethod(newline, "join", "(O)", traceback_list)); Py_DECREF(pErrTraceback); Py_DECREF(traceback_list); } if (IsAbortedTransactionBlockState()) { severity = WARNING; } else { severity = ERROR; } if (errstart(severity, __FILE__, __LINE__, PG_FUNCNAME_MACRO, TEXTDOMAIN)) { if (errstart(severity, __FILE__, __LINE__, PG_FUNCNAME_MACRO, TEXTDOMAIN)) errmsg("Error in python: %s", errName); errdetail("%s", errValue); errdetail_log("%s", errTraceback); } Py_DECREF(pErrType); Py_DECREF(pErrValue); Py_DECREF(format_exception); Py_DECREF(tracebackModule); Py_DECREF(newline); Py_DECREF(pTemp); errfinish(0); }
/* * ExceptionalCondition - Handles the failure of an Assert() * * Note: this can't actually return, but we declare it as returning int * because the TrapMacro() macro might get wonky otherwise. */ int ExceptionalCondition(const char *conditionName, const char *errorType, const char *fileName, int lineNumber) { /* CDB: Try to tell the QD or client what happened. */ if (errstart(FATAL, fileName, lineNumber, NULL,TEXTDOMAIN)) { if (!PointerIsValid(conditionName) || !PointerIsValid(fileName) || !PointerIsValid(errorType)) errfinish(errcode(ERRCODE_INTERNAL_ERROR), errFatalReturn(gp_reraise_signal), errmsg("TRAP: ExceptionalCondition: bad arguments")); else errfinish(errcode(ERRCODE_INTERNAL_ERROR), errFatalReturn(gp_reraise_signal), errmsg("Unexpected internal error"), errdetail("%s(\"%s\", File: \"%s\", Line: %d)\n", errorType, conditionName, fileName, lineNumber) ); /* Usually this shouldn't be needed, but make sure the msg went out */ fflush(stderr); } abort(); return 0; }
/* * A function having everything to do with logging, which ought to be factored * out one day to make a start on the Thoughts-on-logging wiki ideas. */ static void reLogWithChangedLevel(int level) { ErrorData *edata = CopyErrorData(); int sqlstate = edata->sqlerrcode; int category = ERRCODE_TO_CATEGORY(sqlstate); FlushErrorState(); if ( WARNING > level ) { if ( ERRCODE_SUCCESSFUL_COMPLETION != category ) sqlstate = ERRCODE_SUCCESSFUL_COMPLETION; } else if ( WARNING == level ) { if ( ERRCODE_WARNING != category && ERRCODE_NO_DATA != category ) sqlstate = ERRCODE_WARNING; } else if ( ERRCODE_WARNING == category || ERRCODE_NO_DATA == category || ERRCODE_SUCCESSFUL_COMPLETION == category ) sqlstate = ERRCODE_INTERNAL_ERROR; #if PG_VERSION_NUM >= 90500 edata->elevel = level; edata->sqlerrcode = sqlstate; PG_TRY(); { ThrowErrorData(edata); } PG_CATCH(); { FreeErrorData(edata); /* otherwise this wouldn't happen in ERROR case */ PG_RE_THROW(); } PG_END_TRY(); FreeErrorData(edata); #else if (!errstart(level, edata->filename, edata->lineno, edata->funcname, NULL)) { FreeErrorData(edata); return; } errcode(sqlstate); if (edata->message) errmsg("%s", edata->message); if (edata->detail) errdetail("%s", edata->detail); if (edata->detail_log) errdetail_log("%s", edata->detail_log); if (edata->hint) errhint("%s", edata->hint); if (edata->context) errcontext("%s", edata->context); /* this may need to be trimmed */ #if PG_VERSION_NUM >= 90300 if (edata->schema_name) err_generic_string(PG_DIAG_SCHEMA_NAME, edata->schema_name); if (edata->table_name) err_generic_string(PG_DIAG_TABLE_NAME, edata->table_name); if (edata->column_name) err_generic_string(PG_DIAG_COLUMN_NAME, edata->column_name); if (edata->datatype_name) err_generic_string(PG_DIAG_DATATYPE_NAME, edata->datatype_name); if (edata->constraint_name) err_generic_string(PG_DIAG_CONSTRAINT_NAME, edata->constraint_name); #endif if (edata->internalquery) internalerrquery(edata->internalquery); FreeErrorData(edata); errfinish(0); #endif }
static PyObject * log_to_postgres(PyObject *self, PyObject *args, PyObject *kwargs) { char *message = NULL; char *hintstr = NULL, *detailstr = NULL; int level = 1; int severity; PyObject *hint, *p_message, *detail; if (!PyArg_ParseTuple(args, "O|i", &p_message, &level)) { errorCheck(); Py_INCREF(Py_None); return Py_None; } if (PyBytes_Check(p_message)) { message = PyBytes_AsString(p_message); } else if (PyUnicode_Check(p_message)) { message = strdup(PyUnicode_AsPgString(p_message)); } else { PyObject *temp = PyObject_Str(p_message); errorCheck(); message = strdup(PyString_AsString(temp)); errorCheck(); Py_DECREF(temp); } switch (level) { case 0: severity = DEBUG1; break; case 1: severity = NOTICE; break; case 2: severity = WARNING; break; case 3: severity = ERROR; break; case 4: severity = FATAL; break; default: severity = INFO; break; } hint = PyDict_GetItemString(kwargs, "hint"); detail = PyDict_GetItemString(kwargs, "detail"); if (errstart(severity, __FILE__, __LINE__, PG_FUNCNAME_MACRO, TEXTDOMAIN)) { errmsg("%s", message); if (hint != NULL && hint != Py_None) { hintstr = PyString_AsString(hint); errhint("%s", hintstr); } if (detail != NULL && detail != Py_None) { detailstr = PyString_AsString(detail); errdetail("%s", detailstr); } Py_DECREF(args); Py_DECREF(kwargs); errfinish(0); } else { Py_DECREF(args); Py_DECREF(kwargs); } Py_INCREF(Py_None); return Py_None; }
static char* dbms_utility_format_call_stack(char mode) { MemoryContext oldcontext = CurrentMemoryContext; ErrorData *edata; ErrorContextCallback *econtext; StringInfo sinfo; #if PG_VERSION_NUM >= 80400 errstart(ERROR, __FILE__, __LINE__, PG_FUNCNAME_MACRO, TEXTDOMAIN); #else errstart(ERROR, __FILE__, __LINE__, PG_FUNCNAME_MACRO); #endif MemoryContextSwitchTo(oldcontext); for (econtext = error_context_stack; econtext != NULL; econtext = econtext->previous) (*econtext->callback) (econtext->arg); edata = CopyErrorData(); FlushErrorState(); /* Now I wont to parse edata->context to more traditional format */ /* I am not sure about order */ sinfo = makeStringInfo(); switch (mode) { case 'o': appendStringInfoString(sinfo, "----- PL/pgSQL Call Stack -----\n"); appendStringInfoString(sinfo, " object line object\n"); appendStringInfoString(sinfo, " handle number name\n"); break; } if (edata->context) { char *start = edata->context; while (*start) { char *oname = "anonymous object"; char *line = ""; char *eol = strchr(start, '\n'); Oid fnoid = InvalidOid; /* first, solve multilines */ if (eol) *eol = '\0'; /* first know format */ if (strncmp(start, "PL/pgSQL function ",18) == 0) { char *p1, *p2; if ((p1 = strstr(start, "function \""))) { p1 += strlen("function \""); if ((p2 = strchr(p1, '"'))) { *p2++ = '\0'; oname = p1; start = p2; } } else if ((p1 = strstr(start, "function "))) { p1 += strlen("function "); if ((p2 = strchr(p1, ')'))) { char c = *++p2; *p2 = '\0'; oname = pstrdup(p1); fnoid = DatumGetObjectId(DirectFunctionCall1(regprocedurein, CStringGetDatum(oname))); *p2 = c; start = p2; } } if ((p1 = strstr(start, "line "))) { int p2i; char c; p1 += strlen("line "); p2i = strspn(p1, "0123456789"); /* safe separator */ c = p1[p2i]; p1[p2i] = '\0'; line = pstrdup(p1); p1[p2i] = c; start = p1 + p2i; } } switch (mode) { case 'o': appendStringInfo(sinfo, "%8x %5s function %s", (int)fnoid, line, oname); break; case 'p': appendStringInfo(sinfo, "%8d %5s function %s", (int)fnoid, line, oname); break; case 's': appendStringInfo(sinfo, "%d,%s,%s", (int)fnoid, line, oname); break; } if (eol) { start = eol + 1; appendStringInfoChar(sinfo, '\n'); } else break; } } return sinfo->data; }
//--------------------------------------------------------------------------- // @function: // CGPOptimizer::PlstmtOptimize // // @doc: // Optimize given query using GP optimizer // //--------------------------------------------------------------------------- PlannedStmt * CGPOptimizer::PplstmtOptimize ( Query *pquery, bool *pfUnexpectedFailure // output : set to true if optimizer unexpectedly failed to produce plan ) { SOptContext octx; PlannedStmt* plStmt = NULL; GPOS_TRY { plStmt = COptTasks::PplstmtOptimize(pquery, &octx, pfUnexpectedFailure); // clean up context octx.Free(octx.epinQuery, octx.epinPlStmt); } GPOS_CATCH_EX(ex) { // clone the error message before context free. CHAR* szErrorMsg = octx.CloneErrorMsg(MessageContext); // clean up context octx.Free(octx.epinQuery, octx.epinPlStmt); // Special handler for a few common user-facing errors. In particular, // we want to use the correct error code for these, in case an application // tries to do something smart with them. Also, ERRCODE_INTERNAL_ERROR // is handled specially in elog.c, and we don't want that for "normal" // application errors. if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL, gpdxl::ExmiQuery2DXLNotNullViolation)) { errstart(ERROR, ex.SzFilename(), ex.UlLine(), NULL, TEXTDOMAIN); errfinish(errcode(ERRCODE_NOT_NULL_VIOLATION), errmsg("%s", szErrorMsg)); } else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL, gpdxl::ExmiOptimizerError) || NULL != szErrorMsg) { Assert(NULL != szErrorMsg); errstart(ERROR, ex.SzFilename(), ex.UlLine(), NULL, TEXTDOMAIN); errfinish(errcode(ERRCODE_INTERNAL_ERROR), errmsg("%s", szErrorMsg)); } else if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError)) { PG_RE_THROW(); } else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL, gpdxl::ExmiNoAvailableMemory)) { errstart(ERROR, ex.SzFilename(), ex.UlLine(), NULL, TEXTDOMAIN); errfinish(errcode(ERRCODE_INTERNAL_ERROR), errmsg("No available memory to allocate string buffer.")); } else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL, gpdxl::ExmiInvalidComparisonTypeCode)) { errstart(ERROR, ex.SzFilename(), ex.UlLine(), NULL, TEXTDOMAIN); errfinish(errcode(ERRCODE_INTERNAL_ERROR), errmsg("Invalid comparison type code. Valid values are Eq, NEq, LT, LEq, GT, GEq.")); } } GPOS_CATCH_END; return plStmt; }