mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
454 lines
16 KiB
454 lines
16 KiB
#include "../deps/json/json.hpp"
|
|
using json = nlohmann::json;
|
|
#define PROXYJSON
|
|
|
|
#include "PgSQL_Error_Helper.h"
|
|
#include "proxysql.h"
|
|
#include "cpp.h"
|
|
#include "libpq-fe.h"
|
|
|
|
constexpr const char* PgSQL_Error_Helper::error_code_str[];
|
|
|
|
PGSQL_ERROR_CODES PgSQL_Error_Helper::identify_error_code(const char* errorCode) {
|
|
if (strlen(errorCode) != 5)
|
|
return PGSQL_ERROR_CODES::ERRCODE_UNKNOWN;
|
|
|
|
for (uint8_t i = 0; i < static_cast<uint8_t>(PGSQL_ERROR_CODES::PGSQL_ERROR_CODES_COUNT); i++) {
|
|
if (strncmp(errorCode, error_code_str[i], 5) == 0) {
|
|
return static_cast<PGSQL_ERROR_CODES>(i);
|
|
}
|
|
}
|
|
|
|
return PGSQL_ERROR_CODES::ERRCODE_UNKNOWN;
|
|
}
|
|
|
|
PGSQL_ERROR_CLASS PgSQL_Error_Helper::identify_error_class(const char* errorCode) {
|
|
if (strncmp(errorCode, "00", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_SUCCESS;
|
|
}
|
|
else if (strncmp(errorCode, "01", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_WARNING;
|
|
}
|
|
else if (strncmp(errorCode, "02", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_NO_DATA;
|
|
}
|
|
else if (strncmp(errorCode, "03", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_SQL_STATEMENT_NOT_YET_COMPLETE;
|
|
}
|
|
else if (strncmp(errorCode, "08", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_CONNECTION_EXCEPTION;
|
|
}
|
|
else if (strncmp(errorCode, "09", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_TRIGGERED_ACTION_EXCEPTION;
|
|
}
|
|
else if (strncmp(errorCode, "0A", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_FEATURE_NOT_SUPPORTED;
|
|
}
|
|
else if (strncmp(errorCode, "0B", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_TRANSACTION_INITIATION;
|
|
}
|
|
else if (strncmp(errorCode, "0F", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_LOCATOR_EXCEPTION;
|
|
}
|
|
else if (strncmp(errorCode, "0L", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_GRANTOR;
|
|
}
|
|
else if (strncmp(errorCode, "0P", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_ROLE_SPECIFICATION;
|
|
}
|
|
else if (strncmp(errorCode, "0Z", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_DIAGNOSTICS_EXCEPTION;
|
|
}
|
|
else if (strncmp(errorCode, "20", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_CASE_NOT_FOUND;
|
|
}
|
|
else if (strncmp(errorCode, "21", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_CARDINALITY_VIOLATION;
|
|
}
|
|
else if (strncmp(errorCode, "22", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_DATA_EXCEPTION;
|
|
}
|
|
else if (strncmp(errorCode, "23", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INTEGRITY_CONSTRAINT_VIOLATION;
|
|
}
|
|
else if (strncmp(errorCode, "24", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_CURSOR_STATE;
|
|
}
|
|
else if (strncmp(errorCode, "25", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_TRANSACTION_STATE;
|
|
}
|
|
else if (strncmp(errorCode, "26", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_SQL_STATEMENT_NAME;
|
|
}
|
|
else if (strncmp(errorCode, "27", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_TRIGGERED_DATA_CHANGE_VIOLATION;
|
|
}
|
|
else if (strncmp(errorCode, "28", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_AUTHORIZATION_SPECIFICATION;
|
|
}
|
|
else if (strncmp(errorCode, "2B", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST;
|
|
}
|
|
else if (strncmp(errorCode, "2D", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_TRANSACTION_TERMINATION;
|
|
}
|
|
else if (strncmp(errorCode, "2F", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_SQL_ROUTINE_EXCEPTION;
|
|
}
|
|
else if (strncmp(errorCode, "34", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_CURSOR_NAME;
|
|
}
|
|
else if (strncmp(errorCode, "38", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_EXTERNAL_ROUTINE_EXCEPTION;
|
|
}
|
|
else if (strncmp(errorCode, "39", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION;
|
|
}
|
|
else if (strncmp(errorCode, "3B", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_SAVEPOINT_EXCEPTION;
|
|
}
|
|
else if (strncmp(errorCode, "3D", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_CATALOG_NAME;
|
|
}
|
|
else if (strncmp(errorCode, "3F", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INVALID_SCHEMA_NAME;
|
|
}
|
|
else if (strncmp(errorCode, "40", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_TRANSACTION_ROLLBACK;
|
|
}
|
|
else if (strncmp(errorCode, "42", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION;
|
|
}
|
|
else if (strncmp(errorCode, "44", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_WITH_CHECK_OPTION_VIOLATION;
|
|
}
|
|
else if (strncmp(errorCode, "53", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
else if (strncmp(errorCode, "54", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_PROGRAM_LIMIT_EXCEEDED;
|
|
}
|
|
else if (strncmp(errorCode, "55", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_OBJECT_NOT_IN_PREREQUISITE_STATE;
|
|
}
|
|
else if (strncmp(errorCode, "57", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_OPERATOR_INTERVENTION;
|
|
}
|
|
else if (strncmp(errorCode, "58", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_SYSTEM_ERROR_UNSPECIFIED;
|
|
}
|
|
else if (strncmp(errorCode, "72", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_CRASH_SHUTDOWN;
|
|
}
|
|
else if (strncmp(errorCode, "F0", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_CONFIG_FILE_ERROR;
|
|
}
|
|
else if (strncmp(errorCode, "HV", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_FOREIGN_DATA_WRAPPER_ERROR;
|
|
}
|
|
else if (strncmp(errorCode, "P0", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_PLPGSQL_ERROR;
|
|
}
|
|
else if (strncmp(errorCode, "XX", 2) == 0) {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_INTERNAL_ERROR;
|
|
}
|
|
else {
|
|
return PGSQL_ERROR_CLASS::ERRCLASS_UNKNOWN_ERROR;
|
|
}
|
|
}
|
|
|
|
PGSQL_ERROR_CATEGORY PgSQL_Error_Helper::categorize_error_class(PGSQL_ERROR_CLASS err_class) {
|
|
switch (err_class) {
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_SUCCESS:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_WARNING:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_NO_DATA:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_SQL_STATEMENT_NOT_YET_COMPLETE:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_STATUS;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_CONNECTION_EXCEPTION:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_CONNECTION_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INVALID_AUTHORIZATION_SPECIFICATION:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INVALID_GRANTOR:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INVALID_ROLE_SPECIFICATION:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_AUTHORIZATION_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INSUFFICIENT_RESOURCES:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_RESOURCE_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_CONFIG_FILE_ERROR:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_CONFIGURATION_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_SYNTAX_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_FEATURE_NOT_SUPPORTED:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_FEATURE_NOT_SUPPORTED;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_TRIGGERED_ACTION_EXCEPTION:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INVALID_TRANSACTION_INITIATION:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INVALID_TRANSACTION_STATE:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INVALID_TRANSACTION_TERMINATION:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_TRANSACTION_ROLLBACK:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_SAVEPOINT_EXCEPTION:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_TRANSACTION_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_CASE_NOT_FOUND:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_CARDINALITY_VIOLATION:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_DATA_EXCEPTION:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INTEGRITY_CONSTRAINT_VIOLATION:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_WITH_CHECK_OPTION_VIOLATION:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_DATA_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_SQL_ROUTINE_EXCEPTION:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_TRIGGERED_DATA_CHANGE_VIOLATION:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_ROUTINE_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INVALID_CURSOR_STATE:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INVALID_CURSOR_NAME:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_CURSOR_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_EXTERNAL_ROUTINE_EXCEPTION:
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_EXTERNAL_ROUTINE_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_PROGRAM_LIMIT_EXCEEDED:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_RESOURCE_LIMIT_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_OBJECT_NOT_IN_PREREQUISITE_STATE:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_OBJECT_STATE_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_OPERATOR_INTERVENTION:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_OPERATOR_INTERVENTION_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_FOREIGN_DATA_WRAPPER_ERROR:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_FDW_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_PLPGSQL_ERROR:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_PLPGSQL_ERROR;
|
|
|
|
case PGSQL_ERROR_CLASS::ERRCLASS_INTERNAL_ERROR:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_INTERNAL_ERROR_CATEGORY;
|
|
|
|
default:
|
|
return PGSQL_ERROR_CATEGORY::ERRCATEGORY_UNKNOWN_CATEGORY;
|
|
}
|
|
}
|
|
|
|
PGSQL_ERROR_SEVERITY PgSQL_Error_Helper::identify_error_severity(const char* severity) {
|
|
|
|
PGSQL_ERROR_SEVERITY ret = PGSQL_ERROR_SEVERITY::ERRSEVERITY_UNKNOWN_SEVERITY;
|
|
|
|
if (strcasecmp(severity, "PANIC") == 0) {
|
|
ret = PGSQL_ERROR_SEVERITY::ERRSEVERITY_PANIC;
|
|
} else if (strcasecmp(severity, "FATAL") == 0) {
|
|
ret = PGSQL_ERROR_SEVERITY::ERRSEVERITY_FATAL;
|
|
} else if (strcasecmp(severity, "ERROR") == 0) {
|
|
ret = PGSQL_ERROR_SEVERITY::ERRSEVERITY_ERROR;
|
|
} else if (strcasecmp(severity, "WARNING") == 0) {
|
|
ret = PGSQL_ERROR_SEVERITY::ERRSEVERITY_WARNING;
|
|
} else if (strcasecmp(severity, "NOTICE") == 0) {
|
|
ret = PGSQL_ERROR_SEVERITY::ERRSEVERITY_NOTICE;
|
|
} else if (strcasecmp(severity, "DEBUG") == 0) {
|
|
ret = PGSQL_ERROR_SEVERITY::ERRSEVERITY_DEBUG;
|
|
} else if (strcasecmp(severity, "LOG") == 0) {
|
|
ret = PGSQL_ERROR_SEVERITY::ERRSEVERITY_LOG;
|
|
} else if (strcasecmp(severity, "INFO") == 0) {
|
|
ret = PGSQL_ERROR_SEVERITY::ERRSEVERITY_INFO;
|
|
} else {
|
|
ret = PGSQL_ERROR_SEVERITY::ERRSEVERITY_UNKNOWN_SEVERITY;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
void PgSQL_ErrorInfo_Ext::reset() {
|
|
text = PGSQL_ERROR_SEVERITY::ERRSEVERITY_UNKNOWN_SEVERITY;
|
|
detail.clear();
|
|
hint.clear();
|
|
position.clear();
|
|
internal_position.clear();
|
|
internal_query.clear();
|
|
context.clear();
|
|
schema_name.clear();
|
|
table_name.clear();
|
|
column_name.clear();
|
|
datatype_name.clear();
|
|
constraint_name.clear();
|
|
source_file.clear();
|
|
source_line.clear();
|
|
source_function.clear();
|
|
}
|
|
|
|
void PgSQL_Error_Helper::fill_error_info(PgSQL_ErrorInfo& err_info, const char* code, const char* msg, const char* severity) {
|
|
strncpy(err_info.sqlstate, code, 5);
|
|
err_info.sqlstate[5] = '\0';
|
|
err_info.severity = PgSQL_Error_Helper::identify_error_severity(severity);
|
|
err_info.code = PgSQL_Error_Helper::identify_error_code(code);
|
|
err_info.type = PgSQL_Error_Helper::identify_error_class(code);
|
|
err_info.category = PgSQL_Error_Helper::categorize_error_class(err_info.type);
|
|
err_info.message = msg;
|
|
}
|
|
|
|
void PgSQL_Error_Helper::fill_error_info(PgSQL_ErrorInfo& err_info, PGSQL_ERROR_CODES code, const char* msg, PGSQL_ERROR_SEVERITY severity) {
|
|
fill_error_info(err_info, get_error_code(code), msg, PgSQL_Error_Helper::get_severity(severity));
|
|
}
|
|
|
|
/*
|
|
void PgSQL_Error_Helper::fill_error_info_from_error_message(PgSQL_ErrorInfo& err_info, const char* error_msg) {
|
|
std::string errorMsgStr(error_msg);
|
|
std::string sqlState;
|
|
std::string primaryErrorMsg;
|
|
std::string severity;
|
|
|
|
// Initialize positions
|
|
size_t startPos = 0;
|
|
size_t endPos = 0;
|
|
|
|
// Extract severity (assume it's the first word in the primary error message)
|
|
size_t severityEndPos = errorMsgStr.find(": ");
|
|
if (severityEndPos != std::string::npos) {
|
|
severity = errorMsgStr.substr(0, severityEndPos);
|
|
startPos = severityEndPos + 2; // Skip the ": "
|
|
} else {
|
|
severity = get_severity(PGSQL_ERROR_SEVERITY::ERRSEVERITY_UNKNOWN_SEVERITY);
|
|
}
|
|
|
|
// Extract SQL state in the format [XXXXX]
|
|
startPos = errorMsgStr.find('[', startPos);
|
|
endPos = (startPos != std::string::npos) ? errorMsgStr.find(']', startPos) : std::string::npos;
|
|
|
|
if (startPos != std::string::npos && endPos != std::string::npos && endPos == startPos + 6) {
|
|
sqlState = errorMsgStr.substr(startPos + 1, 5); // Extract the SQL state
|
|
primaryErrorMsg = errorMsgStr.substr(severityEndPos + 2, startPos - (severityEndPos + 2)); // Extract the primary error message up to the SQL state
|
|
} else {
|
|
sqlState = get_error_code(PGSQL_ERROR_CODES::ERRCODE_RAISE_EXCEPTION); // Default SQL state
|
|
primaryErrorMsg = errorMsgStr.substr(severityEndPos + 2); // No SQL state found, remainder is the error message
|
|
}
|
|
|
|
fill_error_info(err_info, sqlState.c_str(), primaryErrorMsg.c_str(), severity.c_str());
|
|
}
|
|
*/
|
|
|
|
void reset_error_info(PgSQL_ErrorInfo& err_info, bool release_extented) {
|
|
err_info.sqlstate[0] = '\0';
|
|
err_info.code = PGSQL_ERROR_CODES::ERRCODE_SUCCESSFUL_COMPLETION;
|
|
err_info.severity = PGSQL_ERROR_SEVERITY::ERRSEVERITY_UNKNOWN_SEVERITY;
|
|
err_info.type = PGSQL_ERROR_CLASS::ERRCLASS_UNKNOWN_ERROR;
|
|
err_info.category = PGSQL_ERROR_CATEGORY::ERRCATEGORY_UNKNOWN_CATEGORY;
|
|
err_info.message.clear();
|
|
if (err_info.ext_info) {
|
|
if (release_extented) {
|
|
delete err_info.ext_info;
|
|
err_info.ext_info = NULL;
|
|
} else {
|
|
err_info.ext_info->reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
void PgSQL_Error_Helper::fill_extended_error_info(PgSQL_ErrorInfo& err_info, const PGresult* result, uint16_t ext_fields) {
|
|
|
|
if (ext_fields == 0) {
|
|
if (err_info.ext_info != NULL) {
|
|
delete err_info.ext_info;
|
|
err_info.ext_info = NULL;
|
|
}
|
|
return;
|
|
}
|
|
|
|
char* val = NULL;
|
|
|
|
if (err_info.ext_info == NULL) {
|
|
err_info.ext_info = new PgSQL_ErrorInfo_Ext();
|
|
} else {
|
|
err_info.ext_info->reset();
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_TEXT) {
|
|
val = PQresultErrorField(result, PG_DIAG_SEVERITY_NONLOCALIZED);
|
|
err_info.ext_info->text = identify_error_severity(val ? val : "");
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_DETAIL) {
|
|
val = PQresultErrorField(result, PG_DIAG_MESSAGE_DETAIL);
|
|
err_info.ext_info->detail = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_HINT) {
|
|
val = PQresultErrorField(result, PG_DIAG_MESSAGE_HINT);
|
|
err_info.ext_info->hint = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_POSITION) {
|
|
val = PQresultErrorField(result, PG_DIAG_STATEMENT_POSITION);
|
|
err_info.ext_info->position = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_INTERNAL_POSITION) {
|
|
val = PQresultErrorField(result, PG_DIAG_INTERNAL_POSITION);
|
|
err_info.ext_info->internal_position = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_INTERNAL_QUERY) {
|
|
val = PQresultErrorField(result, PG_DIAG_INTERNAL_QUERY);
|
|
err_info.ext_info->internal_query = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_CONTEXT) {
|
|
val = PQresultErrorField(result, PG_DIAG_CONTEXT);
|
|
err_info.ext_info->context = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_SCHEMA_NAME) {
|
|
val = PQresultErrorField(result, PG_DIAG_SCHEMA_NAME);
|
|
err_info.ext_info->schema_name = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_TABLE_NAME) {
|
|
val = PQresultErrorField(result, PG_DIAG_TABLE_NAME);
|
|
err_info.ext_info->table_name = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_COLUMN_NAME) {
|
|
val = PQresultErrorField(result, PG_DIAG_COLUMN_NAME);
|
|
err_info.ext_info->column_name = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_DATA_TYPE_NAME) {
|
|
val = PQresultErrorField(result, PG_DIAG_DATATYPE_NAME);
|
|
err_info.ext_info->datatype_name = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_CONSTRAINT_NAME) {
|
|
val = PQresultErrorField(result, PG_DIAG_CONSTRAINT_NAME);
|
|
err_info.ext_info->constraint_name = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_FILE) {
|
|
val = PQresultErrorField(result, PG_DIAG_SOURCE_FILE);
|
|
err_info.ext_info->source_file = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_LINE) {
|
|
val = PQresultErrorField(result, PG_DIAG_SOURCE_LINE);
|
|
err_info.ext_info->source_line = val ? val : "";
|
|
}
|
|
|
|
if (ext_fields & PGSQL_ERROR_FIELD_ROUTINE) {
|
|
val = PQresultErrorField(result, PG_DIAG_SOURCE_FUNCTION);
|
|
err_info.ext_info->source_function = val ? val : "";
|
|
}
|
|
}
|
|
|
|
void PgSQL_Error_Helper::fill_error_info(PgSQL_ErrorInfo& err_info, const PGresult* result, uint16_t ext_fields) {
|
|
if (result == nullptr) {
|
|
return;
|
|
}
|
|
const char* sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
|
|
const char* message = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
|
|
const char* severity = PQresultErrorField(result, PG_DIAG_SEVERITY);
|
|
fill_error_info(err_info, sqlstate ? sqlstate : "00000", message ? message : "", severity ? severity : "");
|
|
fill_extended_error_info(err_info, result, ext_fields);
|
|
}
|