Index: connection.c
===================================================================
RCS file: /cvsroot/psqlodbc/psqlodbc/connection.c,v
retrieving revision 1.117
diff -u -3 -r1.117 connection.c
--- connection.c	19 Sep 2005 13:31:58 -0000	1.117
+++ connection.c	3 Oct 2005 21:45:28 -0000
@@ -277,6 +277,7 @@
 		free(self->__error_message);
 	self->__error_message = NULL;
 	self->errormsg_created = FALSE;
+	self->__sqlstate[0] = '\0';
 }
 
 
@@ -496,6 +497,19 @@
 	return rv;
 }
 
+void CC_set_sqlstate(ConnectionClass *self, const char *sqlstate)
+{
+    if (sqlstate)
+        snprintf(self->__sqlstate, SQLSTATE_LENGTH, "%s", sqlstate);
+    else
+        self->__sqlstate[0] = '\0';
+}
+
+char *CC_get_sqlstate(ConnectionClass *self)
+{
+    return self->__sqlstate;
+}
+
 static void CC_clear_cursors(ConnectionClass *self, BOOL allcursors)
 {
 	int	i;
@@ -948,6 +962,7 @@
 		rv->__error_message = NULL;
 		rv->__error_number = 0;
 		rv->errormsg_created = FALSE;
+		rv->__sqlstate[0] = '\0';
 
 		rv->status = CONN_NOT_CONNECTED;
 		rv->transact_status = CONN_IN_AUTOCOMMIT;		/* autocommit by default */
@@ -1818,16 +1833,18 @@
 
 	if ( (PQresultStatus(pgres) != PGRES_EMPTY_QUERY) && (PQresultStatus(pgres) != PGRES_TUPLES_OK) )
 	{
-	        snprintf(errbuffer, ERROR_MSG_LENGTH, "%s", PQerrorMessage(self->pgconn));
-
-	        /* Remove the training CR that libpq adds to the message */
-	        pos = strlen(errbuffer);
-	        if (pos)
-	            errbuffer[pos - 1] = '\0';
+		snprintf(errbuffer, ERROR_MSG_LENGTH, "%s", PQerrorMessage(self->pgconn));
+		
+		/* Remove the training CR that libpq adds to the message */
+		pos = strlen(errbuffer);
+		if (pos)
+			errbuffer[pos - 1] = '\0';
 
 		mylog("the server returned the error: %s\n", errbuffer);
 		CC_set_error(self, CONNECTION_SERVER_REPORTED_ERROR, errbuffer);
-	        PQclear(pgres);
+		CC_set_sqlstate(self, PQresultErrorField(pgres, PG_DIAG_SQLSTATE));
+
+		PQclear(pgres);
 		return qres;
 	}
 
Index: connection.h
===================================================================
RCS file: /cvsroot/psqlodbc/psqlodbc/connection.h,v
retrieving revision 1.66
diff -u -3 -r1.66 connection.h
--- connection.h	19 Sep 2005 13:31:58 -0000	1.66
+++ connection.h	3 Oct 2005 21:45:29 -0000
@@ -306,6 +306,7 @@
 	APDFields	apdOptions;
 	char	   *__error_message;
 	int			__error_number;
+	char		__sqlstate[SQLSTATE_LENGTH + 1];  /* Set only by LIBPQ_execute_query() */
 	CONN_Status status;
 	ConnInfo	connInfo;
 	StatementClass **stmts;
@@ -399,6 +400,8 @@
 const char	*CC_get_current_schema(ConnectionClass *conn);
 int		CC_mark_a_plan_to_discard(ConnectionClass *conn, const char *plannm);
 int		CC_discard_marked_plans(ConnectionClass *conn);
+void		CC_set_sqlstate(ConnectionClass *self, const char *sqlstate);
+char		*CC_get_sqlstate(ConnectionClass *self);
 
 /* Accessor functions*/
 PGconn			*LIBPQ_Constructor();
Index: environ.c
===================================================================
RCS file: /cvsroot/psqlodbc/psqlodbc/environ.c,v
retrieving revision 1.53
diff -u -3 -r1.53 environ.c
--- environ.c	19 Sep 2005 13:31:58 -0000	1.53
+++ environ.c	3 Oct 2005 21:45:29 -0000
@@ -352,8 +352,8 @@
 				/* having no stmtstring is also a malloc problem */
 				break;
 			case STMT_ERROR_TAKEN_FROM_BACKEND:
-				pg_sqlstate_set(env, szSqlState, "HY000", "S1000");
-				/* general error */
+				pg_sqlstate_set(env, szSqlState, SC_get_sqlstate(stmt), "S1000");
+				/* Use the ODBC 3 sqlstate reported by the backend. */
 				break;
 			case STMT_INTERNAL_ERROR:
 				pg_sqlstate_set(env, szSqlState, "HY000", "S1000");
Index: psqlodbc.h
===================================================================
RCS file: /cvsroot/psqlodbc/psqlodbc/psqlodbc.h,v
retrieving revision 1.91
diff -u -3 -r1.91 psqlodbc.h
--- psqlodbc.h	19 Sep 2005 13:31:59 -0000	1.91
+++ psqlodbc.h	3 Oct 2005 21:45:29 -0000
@@ -147,7 +147,8 @@
 							 /* see an easy way round this - DJP 24-1-2001 */
 #define MAX_CONNECT_STRING			4096
 #define ERROR_MSG_LENGTH			4096
-#define FETCH_MAX				100 	/* default number of rows to cache
+#define SQLSTATE_LENGTH				8
+#define FETCH_MAX					100 	/* default number of rows to cache
 							 * for declare/fetch */
 #define TUPLE_MALLOC_INC			100
 #define SOCK_BUFFER_SIZE			8192	/* default socket buffer
@@ -281,7 +282,7 @@
         SDWORD  errorsize;
         SWORD   recsize;
         SWORD   errorpos;
-        char    sqlstate[8];
+        char    sqlstate[SQLSTATE_LENGTH];
         Int4    diag_row_count;
         char    __error_message[1];
 }       PG_ErrorInfo;
Index: statement.c
===================================================================
RCS file: /cvsroot/psqlodbc/psqlodbc/statement.c,v
retrieving revision 1.100
diff -u -3 -r1.100 statement.c
--- statement.c	19 Sep 2005 13:31:59 -0000	1.100
+++ statement.c	3 Oct 2005 21:45:29 -0000
@@ -245,6 +245,7 @@
 		rv->__error_message = NULL;
 		rv->__error_number = 0;
 		rv->errormsg_created = FALSE;
+		rv->__sqlstate[0] = '\0';
 
 		rv->statement = NULL;
 		rv->stmt_with_params = NULL;
@@ -844,6 +845,21 @@
 	return rv;
 }
 
+void
+SC_set_sqlstate(StatementClass *self, const char *sqlstate)
+{
+    if (sqlstate)
+        snprintf(self->__sqlstate, SQLSTATE_LENGTH, "%s", sqlstate);
+    else
+        self->__sqlstate[0] = '\0';
+}
+
+char *
+SC_get_sqlstate(StatementClass *self)
+{
+    return self->__sqlstate;
+}
+
 
 time_t
 SC_get_time(StatementClass *stmt)
@@ -1192,10 +1208,11 @@
 		else
 			SC_set_errornumber(self, was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND);
 
-                if (QR_command_fatal(res) && PQstatus(conn->pgconn) == CONNECTION_BAD)
-                {
-                    SC_set_errornumber(self, STMT_BAD_ERROR);
-                }
+		if (QR_command_fatal(res) && PQstatus(conn->pgconn) == CONNECTION_BAD)
+		    SC_set_errornumber(self, STMT_BAD_ERROR);
+
+		if (SC_get_errornumber(self) == STMT_ERROR_TAKEN_FROM_BACKEND)
+			SC_set_sqlstate(self, CC_get_sqlstate(conn));
 
 		/* set cursor before the first tuple in the list */
 		self->currTuple = -1;
Index: statement.h
===================================================================
RCS file: /cvsroot/psqlodbc/psqlodbc/statement.h,v
retrieving revision 1.61
diff -u -3 -r1.61 statement.h
--- statement.h	15 Sep 2005 07:45:44 -0000	1.61
+++ statement.h	3 Oct 2005 21:45:30 -0000
@@ -150,6 +150,7 @@
 	STMT_Status status;
 	char	   *__error_message;
 	int			__error_number;
+	char		__sqlstate[SQLSTATE_LENGTH];
 
 	Int4		currTuple;		/* current absolute row number (GetData,
 								 * SetPos, SQLFetch) */
@@ -322,6 +323,8 @@
 void		SC_full_error_copy(StatementClass *self, const StatementClass *from);
 char		SC_get_error(StatementClass *self, int *number, char **message);
 char		*SC_create_errormsg(const StatementClass *self);
+void		SC_set_sqlstate(StatementClass *self, const char *sqlstate);
+char		*SC_get_sqlstate(StatementClass *self);
 void		SC_set_prepared(StatementClass *self, BOOL);
 RETCODE		SC_initialize_stmts(StatementClass *self, BOOL);
 RETCODE		SC_execute(StatementClass *self);
