forked from huawei/openGauss-server
forbidden nested autonomous transaction
This commit is contained in:
parent
c235237a4c
commit
9717117500
|
|
@ -224,6 +224,13 @@ void pq_parse_errornotice(StringInfo msg, ErrorData *edata)
|
|||
case PG_DIAG_SEVERITY:
|
||||
/* ignore, trusting we'll get a nonlocalized version */
|
||||
break;
|
||||
case PG_DIAG_INTERNEL_ERRCODE:
|
||||
/* ignore */
|
||||
break;
|
||||
case PG_DIAG_MODULE_ID:
|
||||
/* It is always MOD_MAX */
|
||||
edata->mod_id = MOD_MAX;
|
||||
break;
|
||||
case PG_DIAG_SQLSTATE:
|
||||
if (strlen(value) != 5) {
|
||||
elog(ERROR, "invalid SQLSTATE: \"%s\"", value);
|
||||
|
|
|
|||
|
|
@ -198,7 +198,6 @@ static int check_line_validity_in_for_query(PLpgSQL_stmt_forq* stmt, int, int);
|
|||
static void bind_cursor_with_portal(Portal portal, PLpgSQL_execstate *estate, int varno);
|
||||
static char* transform_anonymous_block(char* query);
|
||||
static bool need_recompile_plan(SPIPlanPtr plan);
|
||||
static THR_LOCAL PLpgSQL_expr* sqlstmt = NULL;
|
||||
|
||||
/* ----------
|
||||
* plpgsql_check_line_validity Called by the debugger plugin for
|
||||
|
|
@ -1420,6 +1419,9 @@ static int exec_stmt_block(PLpgSQL_execstate* estate, PLpgSQL_stmt_block* block)
|
|||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("Un-support feature"),
|
||||
errdetail("Trigger doesnot support autonomous transaction")));
|
||||
} else if (t_thrd.autonomous_cxt.isnested) {
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("Un-support feature : Autonomous transaction doesnot support nesting")));
|
||||
} else {
|
||||
estate->autonomous_session = AutonomousSessionStart();
|
||||
}
|
||||
|
|
@ -3905,7 +3907,7 @@ static int exec_stmt_execsql(PLpgSQL_execstate* estate, PLpgSQL_stmt_execsql* st
|
|||
Datum *values = NULL;
|
||||
bool *nulls = NULL;
|
||||
AutonomousResult *aresult = NULL;
|
||||
sqlstmt = stmt->sqlstmt;
|
||||
t_thrd.autonomous_cxt.sqlstmt = stmt->sqlstmt;
|
||||
build_symbol_table(estate, stmt->sqlstmt->ns, &nparams, ¶m_names, ¶m_types);
|
||||
astmt = AutonomousSessionPrepare(estate->autonomous_session, stmt->sqlstmt->query, (int16)nparams, param_types, param_names);
|
||||
|
||||
|
|
@ -5083,7 +5085,7 @@ static int exec_stmt_null(PLpgSQL_execstate* estate, PLpgSQL_stmt* stmt)
|
|||
static int exec_stmt_commit(PLpgSQL_execstate* estate, PLpgSQL_stmt_commit* stmt)
|
||||
{
|
||||
if (estate->autonomous_session) {
|
||||
if (sqlstmt) {
|
||||
if (t_thrd.autonomous_cxt.sqlstmt) {
|
||||
int nparams = 0;
|
||||
int i;
|
||||
const char **param_names = NULL;
|
||||
|
|
@ -5093,7 +5095,7 @@ static int exec_stmt_commit(PLpgSQL_execstate* estate, PLpgSQL_stmt_commit* stmt
|
|||
bool *nulls = NULL;
|
||||
AutonomousResult *aresult = NULL;
|
||||
ereport(LOG, (errmsg("query COMMIT")));
|
||||
build_symbol_table(estate, sqlstmt->ns, &nparams, ¶m_names, ¶m_types);
|
||||
build_symbol_table(estate, t_thrd.autonomous_cxt.sqlstmt->ns, &nparams, ¶m_names, ¶m_types);
|
||||
astmt = AutonomousSessionPrepare(estate->autonomous_session, "COMMIT", (int16)nparams, param_types, param_names);
|
||||
|
||||
values = (Datum *)palloc(nparams * sizeof(*values));
|
||||
|
|
@ -5104,12 +5106,11 @@ static int exec_stmt_commit(PLpgSQL_execstate* estate, PLpgSQL_stmt_commit* stmt
|
|||
}
|
||||
aresult = AutonomousSessionExecutePrepared(astmt, (int16)nparams, values, nulls);
|
||||
exec_set_found(estate, (list_length(aresult->tuples) != 0));
|
||||
sqlstmt = NULL;
|
||||
t_thrd.autonomous_cxt.sqlstmt = NULL;
|
||||
return PLPGSQL_RC_OK;
|
||||
} else {
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("syntax error"),
|
||||
errdetail("In antonomous transaction, commit/rollback must match start transaction")));
|
||||
errmsg("Syntax error: In antonomous transaction, commit/rollback must match start transaction")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5176,7 +5177,7 @@ static int exec_stmt_commit(PLpgSQL_execstate* estate, PLpgSQL_stmt_commit* stmt
|
|||
static int exec_stmt_rollback(PLpgSQL_execstate* estate, PLpgSQL_stmt_rollback* stmt)
|
||||
{
|
||||
if (estate->autonomous_session) {
|
||||
if (sqlstmt) {
|
||||
if (t_thrd.autonomous_cxt.sqlstmt) {
|
||||
int nparams = 0;
|
||||
int i;
|
||||
const char **param_names = NULL;
|
||||
|
|
@ -5186,7 +5187,7 @@ static int exec_stmt_rollback(PLpgSQL_execstate* estate, PLpgSQL_stmt_rollback*
|
|||
bool *nulls = NULL;
|
||||
AutonomousResult *aresult = NULL;
|
||||
ereport(LOG, (errmsg("query ROLLBACK")));
|
||||
build_symbol_table(estate, sqlstmt->ns, &nparams, ¶m_names, ¶m_types);
|
||||
build_symbol_table(estate, t_thrd.autonomous_cxt.sqlstmt->ns, &nparams, ¶m_names, ¶m_types);
|
||||
astmt = AutonomousSessionPrepare(estate->autonomous_session, "ROLLBACK", (int16)nparams, param_types, param_names);
|
||||
|
||||
values = (Datum *)palloc(nparams * sizeof(*values));
|
||||
|
|
@ -5197,13 +5198,12 @@ static int exec_stmt_rollback(PLpgSQL_execstate* estate, PLpgSQL_stmt_rollback*
|
|||
}
|
||||
aresult = AutonomousSessionExecutePrepared(astmt, (int16)nparams, values, nulls);
|
||||
exec_set_found(estate, (list_length(aresult->tuples) != 0));
|
||||
sqlstmt = NULL;
|
||||
t_thrd.autonomous_cxt.sqlstmt = NULL;
|
||||
return PLPGSQL_RC_OK;
|
||||
} else {
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("syntax error"),
|
||||
errdetail("In antonomous transaction, commit/rollback must match start transaction")));
|
||||
}
|
||||
errmsg("Syntax error: In antonomous transaction, commit/rollback must match start transaction")));
|
||||
}
|
||||
}
|
||||
|
||||
const char* PORTAL = "Portal";
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@
|
|||
#include "utils/lsyscache.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/resowner.h"
|
||||
#include "utils/ps_status.h"
|
||||
|
||||
/* Table-of-contents constants for our dynamic shared memory segment. */
|
||||
#define AUTONOMOUS_MAGIC 0x50674267
|
||||
|
|
@ -524,6 +525,8 @@ void autonomous_worker_main(Datum main_arg)
|
|||
(void)gspqsignal(SIGTERM, die);
|
||||
BackgroundWorkerUnblockSignals();
|
||||
|
||||
t_thrd.autonomous_cxt.isnested = true;
|
||||
|
||||
/* Set up a memory context and resource owner. */
|
||||
Assert(t_thrd.utils_cxt.CurrentResourceOwner == NULL);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = ResourceOwnerCreate(NULL, "autonomous");
|
||||
|
|
@ -533,7 +536,6 @@ void autonomous_worker_main(Datum main_arg)
|
|||
ALLOCSET_DEFAULT_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
|
||||
initStringInfo(&(*t_thrd.postgres_cxt.row_description_buf));
|
||||
seg = (char *)DatumGetPointer(main_arg);
|
||||
if (seg == NULL)
|
||||
ereport(ERROR,
|
||||
|
|
@ -586,9 +588,19 @@ void autonomous_worker_main(Datum main_arg)
|
|||
(void)MemoryContextSwitchTo(t_thrd.mem_cxt.msg_mem_cxt);
|
||||
MemoryContextResetAndDeleteChildren(t_thrd.mem_cxt.msg_mem_cxt);
|
||||
|
||||
ProcessCompletedNotifies();
|
||||
pgstat_report_stat(false);
|
||||
pgstat_report_activity(STATE_IDLE, NULL);
|
||||
if (IsAbortedTransactionBlockState()) {
|
||||
set_ps_display("idle in transaction (aborted)", false);
|
||||
pgstat_report_activity(STATE_IDLEINTRANSACTION_ABORTED, NULL);
|
||||
} else if (IsTransactionOrTransactionBlock()) {
|
||||
set_ps_display("idle in transaction", false);
|
||||
pgstat_report_activity(STATE_IDLEINTRANSACTION, NULL);
|
||||
} else {
|
||||
ProcessCompletedNotifies();
|
||||
pgstat_report_stat(false);
|
||||
|
||||
set_ps_display("idle", false);
|
||||
pgstat_report_activity(STATE_IDLE, NULL);
|
||||
}
|
||||
|
||||
shm_mq_receive_stringinfo(command_qh, &msg);
|
||||
ereport(LOG, (errmsg("bgworker receive msg %s", msg.data)));
|
||||
|
|
|
|||
|
|
@ -1381,6 +1381,12 @@ static void knl_t_heartbeat_init(knl_t_heartbeat_context* heartbeat_cxt)
|
|||
heartbeat_cxt->state = NULL;
|
||||
}
|
||||
|
||||
static void knl_t_autonomous_init(knl_t_autonomous_context* autonomous_cxt)
|
||||
{
|
||||
autonomous_cxt->isnested = false;
|
||||
autonomous_cxt->sqlstmt = NULL;
|
||||
}
|
||||
|
||||
static void knl_t_mot_init(knl_t_mot_context* mot_cxt)
|
||||
{
|
||||
mot_cxt->last_error_code = 0;
|
||||
|
|
@ -1498,6 +1504,7 @@ void knl_thread_init(knl_thread_role role)
|
|||
knl_t_heartbeat_init(&t_thrd.heartbeat_cxt);
|
||||
knl_t_poolcleaner_init(&t_thrd.poolcleaner_cxt);
|
||||
knl_t_mot_init(&t_thrd.mot_cxt);
|
||||
knl_t_autonomous_init(&t_thrd.autonomous_cxt);
|
||||
}
|
||||
|
||||
void knl_thread_set_name(const char* name)
|
||||
|
|
|
|||
|
|
@ -2657,6 +2657,13 @@ typedef struct knl_t_heartbeat_context {
|
|||
struct heartbeat_state* state;
|
||||
} knl_t_heartbeat_context;
|
||||
|
||||
/* autonomous_transaction */
|
||||
struct PLpgSQL_expr;
|
||||
typedef struct knl_t_autonomous_context {
|
||||
PLpgSQL_expr* sqlstmt;
|
||||
bool isnested;
|
||||
} knl_t_autonomous_context;
|
||||
|
||||
/* MOT thread attributes */
|
||||
#define MOT_MAX_ERROR_MESSAGE 256
|
||||
#define MOT_MAX_ERROR_FRAMES 32
|
||||
|
|
@ -2731,6 +2738,7 @@ typedef struct knl_thrd_context {
|
|||
knl_t_arch_context arch;
|
||||
knl_t_async_context asy_cxt;
|
||||
knl_t_audit_context audit;
|
||||
knl_t_autonomous_context autonomous_cxt;
|
||||
knl_t_autovacuum_context autovacuum_cxt;
|
||||
knl_t_basebackup_context basebackup_cxt;
|
||||
knl_t_bgwriter_context bgwriter_cxt;
|
||||
|
|
|
|||
Loading…
Reference in New Issue