Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/scripts/scan-warnings.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ if [[ "$SNAPSHOT_ACTIVE_COUNT" -ne 44 ]]; then
ERROR_FOUND=true
fi

if [[ "$LEAK_COUNT" -ne 416 ]]; then
echo "Error: Expected 416 leak warnings, but found $LEAK_COUNT"
if [[ "$LEAK_COUNT" -ne 29 ]]; then
echo "Error: Expected 29 leak warnings, but found $LEAK_COUNT"
ERROR_FOUND=true
fi

Expand Down
46 changes: 42 additions & 4 deletions contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2708,6 +2708,11 @@ StatementEnd_Internal(PLtsql_execstate *estate, PLtsql_stmt *stmt, bool error)
ListCell *l;
PLtsql_expr *expr = ((PLtsql_stmt_execsql *) stmt)->sqlstmt;

/* True if running inside a new-path INSERT EXEC. */
bool insert_exec_active =
(pltsql_plugin_handler_ptr->pltsql_insert_exec_active &&
pltsql_plugin_handler_ptr->pltsql_insert_exec_active());

/*
* XXX: Once an error occurs, the expr and expr->plan may be
* freed. In that case, we've to save the command type in
Expand All @@ -2731,19 +2736,21 @@ StatementEnd_Internal(PLtsql_execstate *estate, PLtsql_stmt *stmt, bool error)
* or if the INSERT itself is an INSERT-EXEC
* and it just returned error.
*/
row_count_valid = !estate->insert_exec &&
row_count_valid =
!estate->insert_exec &&
!insert_exec_active &&
!(markErrorFlag &&
((PLtsql_stmt_execsql *) stmt)->insert_exec);
}
else if (plansource->commandTag == CMDTAG_UPDATE)
{
command_type = TDS_CMD_UPDATE;
row_count_valid = !estate->insert_exec;
row_count_valid = !estate->insert_exec && !insert_exec_active;
}
else if (plansource->commandTag == CMDTAG_DELETE)
{
command_type = TDS_CMD_DELETE;
row_count_valid = !estate->insert_exec;
row_count_valid = !estate->insert_exec && !insert_exec_active;
}

/*
Expand All @@ -2753,7 +2760,7 @@ StatementEnd_Internal(PLtsql_execstate *estate, PLtsql_stmt *stmt, bool error)
else if (plansource->commandTag == CMDTAG_SELECT)
{
command_type = TDS_CMD_SELECT;
row_count_valid = !estate->insert_exec;
row_count_valid = !estate->insert_exec && !insert_exec_active;
}
}
}
Expand All @@ -2774,8 +2781,39 @@ StatementEnd_Internal(PLtsql_execstate *estate, PLtsql_stmt *stmt, bool error)
case PLTSQL_STMT_EXEC_BATCH:
case PLTSQL_STMT_EXEC_SP:
{
/* INSERT EXEC can target any of EXEC, EXEC_BATCH or EXEC_SP */
void *insert_exec = NULL;

is_proc = true;
command_type = TDS_CMD_EXECUTE;

switch (stmt->cmd_type)
{
case PLTSQL_STMT_EXEC:
insert_exec = ((PLtsql_stmt_exec *) stmt)->insert_exec;
break;
case PLTSQL_STMT_EXEC_BATCH:
insert_exec = ((PLtsql_stmt_exec_batch *) stmt)->insert_exec;
break;
case PLTSQL_STMT_EXEC_SP:
insert_exec = ((PLtsql_stmt_exec_sp *) stmt)->insert_exec;
break;
default:
break;
}

/*
* For INSERT EXEC, report the row count set in
* flush_insert_exec_temp_table(). Suppress it when an error is
* pending: the rows are rolled back, no count is sent to the
* client, and a counted DONE left pending here would otherwise
* carry a stale count into the following error DONE token.
*/
if (!markErrorFlag && insert_exec != NULL)
{
command_type = TDS_CMD_INSERT;
row_count_valid = true;
}
}
break;
default:
Expand Down
4 changes: 2 additions & 2 deletions contrib/babelfishpg_tsql/src/guc.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ bool pltsql_disable_batch_auto_commit = false;
bool pltsql_disable_internal_savepoint = false;
bool pltsql_disable_txn_in_triggers = false;
bool pltsql_recursive_triggers = false;
bool pltsql_enable_new_insert_exec = false;
bool pltsql_enable_new_insert_exec = true;
bool pltsql_noexec = false;
bool pltsql_showplan_all = false;
bool pltsql_showplan_text = false;
Expand Down Expand Up @@ -957,7 +957,7 @@ define_custom_variables(void)
gettext_noop("Enables INSERT...EXEC redesign code path"),
NULL,
&pltsql_enable_new_insert_exec,
false,
true,
PGC_SUSET,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_DISALLOW_IN_AUTO_FILE,
NULL, NULL, NULL);
Expand Down
6 changes: 4 additions & 2 deletions contrib/babelfishpg_tsql/src/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -3668,8 +3668,10 @@ bbf_object_access_hook(ObjectAccessType access, Oid classId, Oid objectId, int s
*/
if ((access == OAT_POST_ALTER || access == OAT_DROP) && classId == RelationRelationId)
{
if (OidIsValid(insert_exec_ctx.target_rel_oid) && objectId == insert_exec_ctx.target_rel_oid)
insert_exec_ctx.is_target_relation_modified = true;
if (insert_exec_ctx != NULL &&
OidIsValid(insert_exec_ctx->target_rel_oid) &&
objectId == insert_exec_ctx->target_rel_oid)
insert_exec_ctx->is_target_relation_modified = true;
}
}

Expand Down
20 changes: 19 additions & 1 deletion contrib/babelfishpg_tsql/src/iterative_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,22 @@ ignore_catch_block_for_unmapped_error(PLtsql_execstate *estate)
return false;
}

/*
* When a TRY-CATCH is inside the procedure executed by an INSERT EXEC, the
* INSERT EXEC is still in progress. Column/datatype mismatch errors must roll
* back every buffered row, so they bypass the CATCH block and are re-thrown.
*/
static
bool
ignore_catch_block_for_insert_exec(PLtsql_execstate *estate)
{
if (pltsql_insert_exec_error_at_trycatch_level() || !pltsql_insert_exec_active())
return false;

return (estate->cur_error->error != NULL &&
estate->cur_error->error->sqlerrcode == ERRCODE_DATATYPE_MISMATCH);
}

/* Cases where transaction is no longer committable */
static
bool
Expand Down Expand Up @@ -1618,7 +1634,9 @@ exec_stmt_iterative(PLtsql_execstate *estate, ExecCodes *exec_codes, ExecConfig_
* error context */
}
}
if (ignore_catch_block_for_unmapped_error(estate) || terminate_batch)
/* INSERT EXEC: re-throw errors that must abort the whole flush */
if (ignore_catch_block_for_insert_exec(estate) ||
ignore_catch_block_for_unmapped_error(estate) || terminate_batch)
{
elog(DEBUG1, "TSQL TXN Ignore catch block error mapping failed : %d", last_error_mapping_failed);
ReThrowError(estate->cur_error->error);
Expand Down
Loading
Loading