diff --git a/contrib/babelfishpg_tsql/src/cursor.c b/contrib/babelfishpg_tsql/src/cursor.c index e79d8d1b8d6..07548b4ede4 100644 --- a/contrib/babelfishpg_tsql/src/cursor.c +++ b/contrib/babelfishpg_tsql/src/cursor.c @@ -1828,3 +1828,60 @@ pltsql_get_last_stmt_handle(PG_FUNCTION_ARGS) { return current_cursor_prepared_handle; } + +/* + * reset_cached_cursor() + * Cleans up all the stale cursor states and resets the cursor handles. + * This function should be called when a connection is cancelled or terminated. + */ +void +reset_cached_cursor() +{ + HASH_SEQ_STATUS hash_seq; + CursorHashEnt *hentry; + + /* Iterate through the CursorHashTable and clean up each cursor */ + hash_seq_init(&hash_seq, CursorHashTable); + while ((hentry = (CursorHashEnt *) hash_seq_search(&hash_seq)) != NULL) + { + /* Clean up the cursor data */ + if (hentry && hentry->tupdesc) + { + FreeTupleDesc(hentry->tupdesc); + hentry->tupdesc = NULL; + } + + if (hentry && hentry->fetch_buffer) + { + tuplestore_end(hentry->fetch_buffer); + hentry->fetch_buffer = NULL; + } + + if (hentry && hentry->textptr_only_bitmap) + { + pfree(hentry->textptr_only_bitmap); + hentry->textptr_only_bitmap = NULL; + } + } + + /* Terminate the sequential scan and destroy hash tables */ + // hash_seq_term(&hash_seq); + hash_destroy(CursorHashTable); + hash_destroy(CursorPreparedHandleHashTable); + + CursorHashTable = NULL; + CursorPreparedHandleHashTable = NULL; + + /* Delete CursorHashtabContext */ + // MemoryContextReset(CursorHashtabContext); + + /* Re-create the cursor-related data structures */ + pltsql_create_cursor_htab(); + + /* Reset cursor handles */ + current_cursor_handle = CURSOR_HANDLE_INVALID; + current_cursor_prepared_handle = CURSOR_PREPARED_HANDLE_START; + + /* Reset sp_cursor_params */ + reset_sp_cursor_params(); +} diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index 1149d00a279..f976e4dfd05 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -2237,6 +2237,7 @@ int execute_sp_cursorfetch(int cursor_handle, int *fetchtype, int *rownum, int int execute_sp_cursoroption(int cursor_handle, int code, int value); int execute_sp_cursoroption2(int cursor_handle, int code, const char *value); int execute_sp_cursorclose(int cursor_handle); +void reset_cached_cursor(void); /* * Functions in string.c diff --git a/contrib/babelfishpg_tsql/src/session.c b/contrib/babelfishpg_tsql/src/session.c index badb5feefdc..f8bdca3cada 100644 --- a/contrib/babelfishpg_tsql/src/session.c +++ b/contrib/babelfishpg_tsql/src/session.c @@ -206,6 +206,7 @@ void reset_session_properties(void) { reset_cached_batch(); + reset_cached_cursor(); pltsql_explain_only = false; pltsql_explain_analyze = false; }