Commit 76d38cb0 authored by Hiroshi Inoue's avatar Hiroshi Inoue

Changed the error handling as follows.

1) ERRORs cause an SQL_ERROR and the SQLSTATE='S1000'.
2) NOTICEs cause an SQL_SUCCESS_WITH_INFO and the succeeding
   SQLError() returns the NOTICE message.
parent 3709a5ad
...@@ -916,6 +916,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ...@@ -916,6 +916,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
int id; int id;
SocketClass *sock = self->sock; SocketClass *sock = self->sock;
int maxlen; int maxlen;
BOOL msg_truncated;
/* ERROR_MSG_LENGTH is suffcient */ /* ERROR_MSG_LENGTH is suffcient */
static char msgbuffer[ERROR_MSG_LENGTH + 1]; static char msgbuffer[ERROR_MSG_LENGTH + 1];
...@@ -1004,6 +1005,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ...@@ -1004,6 +1005,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
self->errormsg = "No response from backend while receiving a portal query command"; self->errormsg = "No response from backend while receiving a portal query command";
mylog("send_query: 'C' - %s\n", self->errormsg); mylog("send_query: 'C' - %s\n", self->errormsg);
CC_set_no_trans(self); CC_set_no_trans(self);
if (res)
QR_Destructor(res);
return NULL; return NULL;
} }
else else
...@@ -1018,7 +1021,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ...@@ -1018,7 +1021,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer); mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer);
/* Only save the first command */ /* Only save the first command */
QR_set_status(res, PGRES_COMMAND_OK); if (QR_command_successful(res))
QR_set_status(res, PGRES_COMMAND_OK);
QR_set_command(res, cmdbuffer); QR_set_command(res, cmdbuffer);
/* /*
...@@ -1049,11 +1053,16 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ...@@ -1049,11 +1053,16 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
qlog("Command response: '%s'\n", cmdbuffer); qlog("Command response: '%s'\n", cmdbuffer);
break; break;
case 'N': case 'N':
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
if (QR_command_successful(res))
QR_set_status(res, PGRES_NONFATAL_ERROR);
QR_set_notice(res, cmdbuffer); /* will dup this string */
qlog("NOTICE from backend during clear: '%s'\n", cmdbuffer); qlog("NOTICE from backend during clear: '%s'\n", cmdbuffer);
while (msg_truncated)
msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
break; break;
case 'E': case 'E':
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
qlog("ERROR from backend during clear: '%s'\n", cmdbuffer); qlog("ERROR from backend during clear: '%s'\n", cmdbuffer);
/* /*
...@@ -1071,8 +1080,10 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ...@@ -1071,8 +1080,10 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
} }
else else
self->errornumber = CONNECTION_SERVER_REPORTED_WARNING; self->errornumber = CONNECTION_SERVER_REPORTED_WARNING;
QR_set_status(res, PGRES_NONFATAL_ERROR); QR_set_status(res, PGRES_FATAL_ERROR);
QR_set_aborted(res, TRUE); QR_set_aborted(res, TRUE);
while (msg_truncated)
msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
break; break;
} }
} }
...@@ -1088,14 +1099,17 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ...@@ -1088,14 +1099,17 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
case 'Z': /* Backend is ready for new query (6.4) */ case 'Z': /* Backend is ready for new query (6.4) */
break; break;
case 'N': /* NOTICE: */ case 'N': /* NOTICE: */
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
if (!res)
res = QR_Constructor(); res = QR_Constructor();
QR_set_status(res, PGRES_NONFATAL_ERROR); if (QR_command_successful(res))
QR_set_status(res, PGRES_NONFATAL_ERROR);
QR_set_notice(res, cmdbuffer); /* will dup this string */ QR_set_notice(res, cmdbuffer); /* will dup this string */
mylog("~~~ NOTICE: '%s'\n", cmdbuffer); mylog("~~~ NOTICE: '%s'\n", cmdbuffer);
qlog("NOTICE from backend during send_query: '%s'\n", cmdbuffer); qlog("NOTICE from backend during send_query: '%s'\n", cmdbuffer);
while (msg_truncated)
msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
continue; /* dont return a result -- continue continue; /* dont return a result -- continue
* reading */ * reading */
...@@ -1107,20 +1121,22 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ...@@ -1107,20 +1121,22 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
{ {
self->errornumber = CONNECTION_BACKEND_CRAZY; self->errornumber = CONNECTION_BACKEND_CRAZY;
self->errormsg = "Unexpected protocol character from backend (send_query - I)"; self->errormsg = "Unexpected protocol character from backend (send_query - I)";
res = QR_Constructor(); if (!res)
res = QR_Constructor();
QR_set_status(res, PGRES_FATAL_ERROR); QR_set_status(res, PGRES_FATAL_ERROR);
return res; return res;
} }
else else
{ {
/* We return the empty query */ /* We return the empty query */
res = QR_Constructor(); if (!res)
res = QR_Constructor();
QR_set_status(res, PGRES_EMPTY_QUERY); QR_set_status(res, PGRES_EMPTY_QUERY);
return res; return res;
} }
break; break;
case 'E': case 'E':
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); msg_truncated = SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
/* Remove a newline */ /* Remove a newline */
if (msgbuffer[0] != '\0' && msgbuffer[strlen(msgbuffer) - 1] == '\n') if (msgbuffer[0] != '\0' && msgbuffer[strlen(msgbuffer) - 1] == '\n')
...@@ -1132,20 +1148,22 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ...@@ -1132,20 +1148,22 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
qlog("ERROR from backend during send_query: '%s'\n", self->errormsg); qlog("ERROR from backend during send_query: '%s'\n", self->errormsg);
/* We should report that an error occured. Zoltan */ /* We should report that an error occured. Zoltan */
res = QR_Constructor(); if (!res)
res = QR_Constructor();
if (!strncmp(self->errormsg, "FATAL", 5)) if (!strncmp(self->errormsg, "FATAL", 5))
{ {
self->errornumber = CONNECTION_SERVER_REPORTED_ERROR; self->errornumber = CONNECTION_SERVER_REPORTED_ERROR;
CC_set_no_trans(self); CC_set_no_trans(self);
QR_set_status(res, PGRES_FATAL_ERROR);
} }
else else
{ {
self->errornumber = CONNECTION_SERVER_REPORTED_WARNING; self->errornumber = CONNECTION_SERVER_REPORTED_WARNING;
QR_set_status(res, PGRES_NONFATAL_ERROR);
} }
QR_set_status(res, PGRES_FATAL_ERROR);
QR_set_aborted(res, TRUE); QR_set_aborted(res, TRUE);
while (msg_truncated)
msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
return res; /* instead of NULL. Zoltan */ return res; /* instead of NULL. Zoltan */
...@@ -1188,12 +1206,16 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ...@@ -1188,12 +1206,16 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
return result_in; return result_in;
case 'D': /* Copy in command began successfully */ case 'D': /* Copy in command began successfully */
res = QR_Constructor(); if (!res)
QR_set_status(res, PGRES_COPY_IN); res = QR_Constructor();
if (QR_command_successful(res))
QR_set_status(res, PGRES_COPY_IN);
return res; return res;
case 'B': /* Copy out command began successfully */ case 'B': /* Copy out command began successfully */
res = QR_Constructor(); if (!res)
QR_set_status(res, PGRES_COPY_OUT); res = QR_Constructor();
if (QR_command_successful(res))
QR_set_status(res, PGRES_COPY_OUT);
return res; return res;
default: default:
self->errornumber = CONNECTION_BACKEND_CRAZY; self->errornumber = CONNECTION_BACKEND_CRAZY;
...@@ -1201,6 +1223,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ...@@ -1201,6 +1223,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
CC_set_no_trans(self); CC_set_no_trans(self);
mylog("send_query: error - %s\n", self->errormsg); mylog("send_query: error - %s\n", self->errormsg);
if (res)
QR_Destructor(res);
return NULL; return NULL;
} }
} }
......
...@@ -195,17 +195,19 @@ SOCK_put_n_char(SocketClass *self, char *buffer, int len) ...@@ -195,17 +195,19 @@ SOCK_put_n_char(SocketClass *self, char *buffer, int len)
/* /*
* bufsize must include room for the null terminator * bufsize must include room for the null terminator
* will read at most bufsize-1 characters + null. * will read at most bufsize-1 characters + null.
* returns TRUE if truncation occurs.
*/ */
void BOOL
SOCK_get_string(SocketClass *self, char *buffer, int bufsize) SOCK_get_string(SocketClass *self, char *buffer, int bufsize)
{ {
register int lf = 0; register int lf = 0;
for (lf = 0; lf < bufsize; lf++) for (lf = 0; lf < bufsize; lf++)
if (!(buffer[lf] = SOCK_get_next_byte(self))) if (!(buffer[lf] = SOCK_get_next_byte(self)))
return; return FALSE;
buffer[bufsize - 1] = '\0'; buffer[bufsize - 1] = '\0';
return TRUE;
} }
......
...@@ -86,7 +86,7 @@ void SOCK_Destructor(SocketClass *self); ...@@ -86,7 +86,7 @@ void SOCK_Destructor(SocketClass *self);
char SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname); char SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname);
void SOCK_get_n_char(SocketClass *self, char *buffer, int len); void SOCK_get_n_char(SocketClass *self, char *buffer, int len);
void SOCK_put_n_char(SocketClass *self, char *buffer, int len); void SOCK_put_n_char(SocketClass *self, char *buffer, int len);
void SOCK_get_string(SocketClass *self, char *buffer, int bufsize); BOOL SOCK_get_string(SocketClass *self, char *buffer, int bufsize);
void SOCK_put_string(SocketClass *self, char *string); void SOCK_put_string(SocketClass *self, char *string);
int SOCK_get_int(SocketClass *self, short len); int SOCK_get_int(SocketClass *self, short len);
void SOCK_put_int(SocketClass *self, int value, short len); void SOCK_put_int(SocketClass *self, int value, short len);
......
...@@ -652,6 +652,8 @@ SC_create_errormsg(StatementClass *self) ...@@ -652,6 +652,8 @@ SC_create_errormsg(StatementClass *self)
sprintf(&msg[pos], ";\n%s", sock->errormsg); sprintf(&msg[pos], ";\n%s", sock->errormsg);
} }
} }
if (!msg[0] && res && QR_get_notice(res))
return QR_get_notice(res);
return msg; return msg;
} }
...@@ -1044,14 +1046,11 @@ SC_execute(StatementClass *self) ...@@ -1044,14 +1046,11 @@ SC_execute(StatementClass *self)
if (self->errornumber == STMT_OK) if (self->errornumber == STMT_OK)
return SQL_SUCCESS; return SQL_SUCCESS;
else if (self->errornumber == STMT_INFO_ONLY)
return SQL_SUCCESS_WITH_INFO;
else else
{ {
/* Modified, 2000-04-29, Zoltan */ self->errormsg = "Error while executing the query";
if (self->errornumber == STMT_INFO_ONLY)
self->errormsg = "Error while executing the query (non-fatal)";
else
self->errormsg = "Unknown error";
SC_log_error(func, "", self); SC_log_error(func, "", self);
return SQL_ERROR; return SQL_ERROR;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment