BOOL cmd_success;
SPRINTF_FIXED(query, "set client_encoding to '%s'", encoding);
- res = CC_send_query(self, query, NULL, IGNORE_ABORT_ON_CONN | ROLLBACK_ON_ERROR, NULL);
+ res = CC_send_query(self, query, NULL, 0, NULL);
cmd_success = QR_command_maybe_successful(res);
QR_Destructor(res);
CC_set_errornumber(self, errnum);
goto cleanup;
}
- mylog("error message len=%d\n", strlen(errmsg));
+ if (get_mylog() > 0)
+ mylog("error message=%s(%d)\n", errmsg, strlen(errmsg));
if (res)
{
CONNLOCK_RELEASE(self);
wres = CC_send_query(self, cmd, NULL, ROLLBACK_ON_ERROR | IGNORE_ABORT_ON_CONN | READ_ONLY_QUERY, NULL);
QR_set_no_survival_check(res);
- if (QR_command_maybe_successful(wres))
+ if (QR_command_maybe_successful(wres) &&
+ CONN_ERROR_IGNORED != CC_get_errornumber(self))
QR_set_permanent(res);
else
QR_set_cursor(res, NULL);
QR_Destructor(wres);
CONNLOCK_ACQUIRE(self);
+inolog(" !!!! %s:%p->permanent -> %d %p\n", __FUNCTION__, res, QR_is_permanent(res), QR_get_cursor(res));
}
else
QR_set_permanent(res);
char cmd[64];
PGresult *pgres = NULL;
+ if (!CC_is_in_error_trans(self))
+ return 1;
switch (rollback_type)
{
case PER_STATEMENT_ROLLBACK:
LIBPQ_update_transaction_status(self);
break;
}
- if (pgres)
- PQclear(pgres);
break;
case PER_QUERY_ROLLBACK:
+ SPRINTF_FIXED(cmd, "%s TO %s;%s %s"
+ , rbkcmd, per_query_svp , rlscmd, per_query_svp);
+ mylog(" %s:query_rollback PQsendQuery %s\n", __FUNCTION__, cmd);
+ PQsendQuery(self->pqconn, cmd);
+ ret = 1;
+ while (self->pqconn && (pgres = PQgetResult(self->pqconn)) != NULL)
+ {
+ switch (PQresultStatus(pgres))
+ {
+ case PGRES_COMMAND_OK:
+ case PGRES_NONFATAL_ERROR:
+ break;
+ default:
+ ret = 0;
+ }
+ }
+ if (ret)
+ {
+ if (ignore_abort)
+ CC_set_no_error_trans(self);
+ }
+ else
+ mylog(" %s:return error\n", __FUNCTION__);
+ LIBPQ_update_transaction_status(self);
break;
}
+ if (pgres)
+ PQclear(pgres);
+
return ret;
}
used_passed_result_object = FALSE,
discard_next_begin = FALSE,
discard_next_savepoint = FALSE,
+ discard_next_release = FALSE,
consider_rollback;
int func_cs_count = 0, i;
size_t query_buf_len = 0;
{
if (discard_next_savepoint)
{
-inolog("Discarded the first SAVEPOINT\n");
discard_next_savepoint = FALSE;
+ discard_next_release = TRUE;
+inolog("Discarded a SAVEPOINT result\n");
break; /* discard the result */
}
if (SAVEPOINT_IN_PROGRESS == self->internal_op)
}
else if (strnicmp(cmdbuffer, rlscmd, strlen(rlscmd)) == 0)
{
+ if (discard_next_release)
+ {
+inolog("Discarded a RELEASE result\n");
+ discard_next_release = FALSE;
+ break; /* discard the result */
+ }
self->internal_svp = 0;
if (SAVEPOINT_IN_PROGRESS == self->internal_op)
break; /* discard the result */
PQclear(pgres);
pgres = NULL;
}
+inolog(" !!!! %s:rollback_on_error=%d CC_is_in_trans=%d discard_next_savepoint=%d query_rollback=%d\n", __FUNCTION__, rollback_on_error, CC_is_in_trans(self), discard_next_savepoint, query_rollback);
if (rollback_on_error && CC_is_in_trans(self) && !discard_next_savepoint)
{
if (query_rollback)
{
- if (CC_is_in_error_trans(self))
- {
- char tmpsqlbuf[100];
-
- SPRINTF_FIXED(tmpsqlbuf,
- "%s TO %s"
- ";%s %s"
- , rbkcmd, per_query_svp
- , rlscmd, per_query_svp);
- pgres = PQexec(self->pqconn, tmpsqlbuf);
- /*
- * Though it's not appropriate to
- * call PQExec for a multiple command,
- * it seems OK because we don't check
- * the result here.
- */
- }
+ if (!CC_internal_rollback(self, PER_QUERY_ROLLBACK, ignore_abort_on_conn))
+ ignore_abort_on_conn = FALSE;
}
else if (CC_is_in_error_trans(self))
pgres = PQexec(self->pqconn, rbkcmd);
* If error message isn't set
*/
if (ignore_abort_on_conn)
- CC_set_errornumber(self, 0);
+ {
+ CC_set_errornumber(self, CONN_ERROR_IGNORED);
+ if (retres)
+ QR_set_rstatus(retres, PORES_NONFATAL_ERROR);
+inolog(" !!!! %s:ignored abort_on_conn\n", __FUNCTION__);
+ }
else if (retres)
{
if (NULL == CC_get_errormsg(self) ||
SetStatementSvp(StatementClass *stmt, unsigned int option)
{
CSTR func = "SetStatementSvp";
- char esavepoint[32], cmd[64];
+ char cmd[64];
ConnectionClass *conn = SC_get_conn(stmt);
QResultClass *res;
RETCODE ret = SQL_SUCCESS_WITH_INFO;
DiscardStatementSvp(StatementClass *stmt, RETCODE ret, BOOL errorOnly)
{
CSTR func = "DiscardStatementSvp";
- char cmd[64];
ConnectionClass *conn = SC_get_conn(stmt);
- QResultClass *res;
- BOOL cmd_success, start_stmt = FALSE;
+ BOOL start_stmt = FALSE;
inolog("%s:%p->accessed=%d is_in=%d is_rb=%d is_tc=%d\n", func, conn, CC_accessed_db(conn),
CC_is_in_trans(conn), SC_is_rb_stmt(stmt), SC_is_tc_stmt(stmt));
if (!cmd_success)
{
SC_set_error(stmt, STMT_INTERNAL_ERROR, "internal ROLLBACK failed", func);
- CC_abort(conn);
goto cleanup;
}
}