in execute.c [454:679]
RETCODE Exec_with_parameters_resolved(StatementClass *stmt, EXEC_TYPE exec_type, BOOL *exec_end)
{
CSTR func = "Exec_with_parameters_resolved";
RETCODE retval;
SQLLEN start_row, end_row;
SQLINTEGER cursor_type, scroll_concurrency;
ConnectionClass *conn;
QResultClass *res;
APDFields *apdopts;
IPDFields *ipdopts;
BOOL prepare_before_exec = FALSE;
char *stmt_with_params;
SQLLEN status_row = stmt->exec_current_row;
int count_of_deferred;
*exec_end = FALSE;
conn = SC_get_conn(stmt);
MYLOG(MIN_LOG_LEVEL, "copying statement params: trans_status=%d, len=" FORMAT_SIZE_T ", stmt='%s'\n", conn->transact_status, strlen(stmt->statement), stmt->statement);
#define return DONT_CALL_RETURN_FROM_HERE???
#define RETURN(code) { retval = code; goto cleanup; }
ENTER_CONN_CS(conn);
/* save the cursor's info before the execution */
cursor_type = stmt->options.cursor_type;
scroll_concurrency = stmt->options.scroll_concurrency;
/* Prepare the statement if possible at backend side */
if (HowToPrepareBeforeExec(stmt, FALSE) >= allowParse)
prepare_before_exec = TRUE;
MYLOG(DETAIL_LOG_LEVEL, "prepare_before_exec=%d srv=%d\n", prepare_before_exec, stmt->use_server_side_prepare);
/* Create the statement with parameters substituted. */
stmt_with_params = stmt->stmt_with_params;
if (LAST_EXEC == exec_type)
{
if (NULL != stmt_with_params)
{
free(stmt_with_params);
stmt_with_params = stmt->stmt_with_params = NULL;
}
if (INVALID_EXPBUFFER ||
!stmt->stmt_deferred.data[0])
RETURN(SQL_SUCCESS);
}
else
{
retval = copy_statement_with_parameters(stmt, prepare_before_exec);
stmt->current_exec_param = -1;
if (retval != SQL_SUCCESS)
{
stmt->exec_current_row = -1;
*exec_end = TRUE;
RETURN(retval) /* error msg is passed from the above */
}
stmt_with_params = stmt->stmt_with_params;
if (!stmt_with_params) // Extended Protocol
exec_type = DIRECT_EXEC;
}
MYLOG(MIN_LOG_LEVEL, " stmt_with_params = '%s'\n", stmt->stmt_with_params);
/*
* The real execution.
*/
MYLOG(MIN_LOG_LEVEL, "about to begin SC_execute exec_type=%d\n", exec_type);
ipdopts = SC_get_IPDF(stmt);
apdopts = SC_get_APDF(stmt);
if (start_row = stmt->exec_start_row, start_row < 0)
start_row = 0;
if (end_row = stmt->exec_end_row, end_row < 0)
{
end_row = (SQLINTEGER) apdopts->paramset_size - 1;
if (end_row < 0)
end_row = 0;
}
if (LAST_EXEC == exec_type &&
NULL != ipdopts->param_status_ptr)
{
int i;
for (i = end_row; i >= start_row; i--)
{
if (SQL_PARAM_UNUSED != ipdopts->param_status_ptr[i])
{
status_row = i;
break;
}
}
}
count_of_deferred = stmt->count_of_deffered;
if (DIRECT_EXEC == exec_type)
{
retval = SC_execute(stmt);
stmt->count_of_deffered = 0;
}
else if (DEFFERED_EXEC == exec_type &&
stmt->exec_current_row < end_row &&
stmt->count_of_deffered + 1 < stmt->batch_size)
{
if (INVALID_EXPBUFFER)
initPQExpBuffer(&stmt->stmt_deferred);
if (INVALID_EXPBUFFER)
{
retval = SQL_ERROR;
SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory", __FUNCTION__);
}
else
{
if (NULL != stmt_with_params)
{
if (stmt->stmt_deferred.data[0])
appendPQExpBuffer(&stmt->stmt_deferred, ";%s", stmt_with_params);
else
printfPQExpBuffer(&stmt->stmt_deferred, "%s", stmt_with_params);
}
if (NULL != ipdopts->param_status_ptr)
ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS; // set without exec
stmt->count_of_deffered++;
stmt->exec_current_row++;
RETURN(SQL_SUCCESS);
}
}
else
{
if (VALID_EXPBUFFER)
{
if (NULL != stmt_with_params)
appendPQExpBuffer(&stmt->stmt_deferred, ";%s", stmt_with_params);
stmt->stmt_with_params = stmt->stmt_deferred.data;
}
retval = SC_execute(stmt);
stmt->stmt_with_params = stmt_with_params;
stmt->count_of_deffered = 0;
if (VALID_EXPBUFFER)
resetPQExpBuffer(&stmt->stmt_deferred);
}
if (retval == SQL_ERROR)
{
MYLOG(MIN_LOG_LEVEL, "count_of_deferred=%d\n", count_of_deferred);
param_status_batch_update(ipdopts, SQL_PARAM_ERROR, stmt->exec_current_row, count_of_deferred);
stmt->exec_current_row = -1;
*exec_end = TRUE;
RETURN(retval)
}
res = SC_get_Result(stmt);
/* special handling of result for keyset driven cursors */
if (SQL_CURSOR_KEYSET_DRIVEN == stmt->options.cursor_type &&
SQL_CONCUR_READ_ONLY != stmt->options.scroll_concurrency)
{
QResultClass *kres;
if (kres = QR_nextr(res), kres)
{
QR_set_fields(kres, QR_get_fields(res));
QR_set_fields(res, NULL);
kres->num_fields = res->num_fields;
QR_detach(res);
SC_set_Result(stmt, kres);
res = kres;
}
}
ipdopts = SC_get_IPDF(stmt);
if (ipdopts->param_status_ptr)
{
switch (retval)
{
case SQL_SUCCESS:
ipdopts->param_status_ptr[status_row] = SQL_PARAM_SUCCESS;
break;
case SQL_SUCCESS_WITH_INFO:
MYLOG(MIN_LOG_LEVEL, "count_of_deffered=%d has_notice=%d\n", count_of_deferred, stmt->has_notice);
param_status_batch_update(ipdopts, (count_of_deferred > 0 && !stmt->has_notice) ? SQL_PARAM_SUCCESS : SQL_PARAM_SUCCESS_WITH_INFO, status_row, count_of_deferred);
break;
default:
param_status_batch_update(ipdopts, SQL_PARAM_ERROR, status_row, count_of_deferred);
break;
}
}
stmt->has_notice = 0;
if (stmt->exec_current_row >= end_row)
{
*exec_end = TRUE;
stmt->exec_current_row = -1;
}
else
stmt->exec_current_row++;
if (res)
{
EnvironmentClass *env = (EnvironmentClass *) CC_get_env(conn);
const char *cmd = QR_get_command(res);
if (retval == SQL_SUCCESS &&
NULL != cmd &&
start_row >= end_row &&
NULL != env &&
EN_is_odbc3(env))
{
int count;
int status = 0;
if (secure_sscanf(cmd, &status, "UPDATE %d", ARG_INT(&count)) == 1)
;
else if (secure_sscanf(cmd, &status, "DELETE %d", ARG_INT(&count)) == 1)
;
else
count = -1;
if (0 == count)
retval = SQL_NO_DATA;
}
stmt->diag_row_count = res->recent_processed_row_count;
}
/*
* The cursor's info was changed ?
*/
if (retval == SQL_SUCCESS &&
(stmt->options.cursor_type != cursor_type ||
stmt->options.scroll_concurrency != scroll_concurrency))
{
SC_set_error(stmt, STMT_OPTION_VALUE_CHANGED, "cursor updatability changed", func);
retval = SQL_SUCCESS_WITH_INFO;
}
cleanup:
#undef RETURN
#undef return
LEAVE_CONN_CS(conn);
return retval;
}