Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
6428074e
Commit
6428074e
authored
Oct 01, 1998
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update libpq to store an error message in PGresult, per pgsq-interfaces discussion of 21-Sep.
parent
502769d0
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
205 additions
and
79 deletions
+205
-79
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/fe-connect.c
+2
-2
src/interfaces/libpq/fe-exec.c
src/interfaces/libpq/fe-exec.c
+132
-43
src/interfaces/libpq/fe-lobj.c
src/interfaces/libpq/fe-lobj.c
+25
-1
src/interfaces/libpq/libpq-fe.h
src/interfaces/libpq/libpq-fe.h
+33
-26
src/interfaces/libpq/libpq-int.h
src/interfaces/libpq/libpq-int.h
+12
-7
src/interfaces/libpq/libpqdll.def
src/interfaces/libpq/libpqdll.def
+1
-0
No files found.
src/interfaces/libpq/fe-connect.c
View file @
6428074e
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.8
3 1998/09/20 04:51:10 momjian
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.8
4 1998/10/01 01:40:19 tgl
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -822,8 +822,8 @@ PQsetenv(PGconn *conn)
sprintf
(
envbuf
,
"%s=%s"
,
envname
,
encoding
);
putenv
(
envbuf
);
}
PQclear
(
rtn
);
}
PQclear
(
rtn
);
if
(
!
encoding
)
{
/* this should not happen */
sprintf
(
envbuf
,
"%s=%s"
,
envname
,
pg_encoding_to_char
(
MULTIBYTE
));
...
...
src/interfaces/libpq/fe-exec.c
View file @
6428074e
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.6
8 1998/09/10 15:18:02 momjian
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.6
9 1998/10/01 01:40:21 tgl
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -50,7 +50,7 @@ const char *const pgresStatus[] = {
static
void
freeTuple
(
PGresAttValue
*
tuple
,
int
numAttributes
);
static
void
addTuple
(
PGresult
*
res
,
PGresAttValue
*
tup
);
static
int
addTuple
(
PGresult
*
res
,
PGresAttValue
*
tup
);
static
void
parseInput
(
PGconn
*
conn
);
static
int
getRowDescriptions
(
PGconn
*
conn
);
static
int
getAnotherTuple
(
PGconn
*
conn
,
int
binary
);
...
...
@@ -60,7 +60,9 @@ static int getNotice(PGconn *conn);
/*
* PQmakeEmptyPGresult
* returns a newly allocated, initialized PGresult with given status
* returns a newly allocated, initialized PGresult with given status.
* If conn is not NULL and status indicates an error, the conn's
* errorMessage is copied.
*
* Note this is exported --- you wouldn't think an application would need
* to build its own PGresults, but this has proven useful in both libpgtcl
...
...
@@ -74,7 +76,7 @@ PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
result
=
(
PGresult
*
)
malloc
(
sizeof
(
PGresult
));
result
->
conn
=
conn
;
result
->
conn
=
conn
;
/* should go away eventually */
result
->
ntups
=
0
;
result
->
numAttributes
=
0
;
result
->
attDescs
=
NULL
;
...
...
@@ -83,13 +85,45 @@ PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
result
->
resultStatus
=
status
;
result
->
cmdStatus
[
0
]
=
'\0'
;
result
->
binary
=
0
;
result
->
errMsg
=
NULL
;
if
(
conn
)
/* consider copying conn's errorMessage */
{
switch
(
status
)
{
case
PGRES_EMPTY_QUERY
:
case
PGRES_COMMAND_OK
:
case
PGRES_TUPLES_OK
:
case
PGRES_COPY_OUT
:
case
PGRES_COPY_IN
:
/* non-error cases */
break
;
default:
pqSetResultError
(
result
,
conn
->
errorMessage
);
break
;
}
}
return
result
;
}
/*
* pqSetResultError -
* assign a new error message to a PGresult
*/
void
pqSetResultError
(
PGresult
*
res
,
const
char
*
msg
)
{
if
(
!
res
)
return
;
if
(
res
->
errMsg
)
free
(
res
->
errMsg
);
res
->
errMsg
=
NULL
;
if
(
msg
&&
*
msg
)
res
->
errMsg
=
strdup
(
msg
);
}
/*
* PQclear -
* free's the memory associated with a PGresult
*
*/
void
PQclear
(
PGresult
*
res
)
...
...
@@ -118,6 +152,10 @@ PQclear(PGresult *res)
free
(
res
->
attDescs
);
}
/* free the error text */
if
(
res
->
errMsg
)
free
(
res
->
errMsg
);
/* free the structure itself */
free
(
res
);
}
...
...
@@ -164,27 +202,35 @@ pqClearAsyncResult(PGconn *conn)
/*
* addTuple
* add a row to the PGresult structure, growing it if necessary
* Returns TRUE if OK, FALSE if not enough memory to add the row
*/
static
void
static
int
addTuple
(
PGresult
*
res
,
PGresAttValue
*
tup
)
{
if
(
res
->
ntups
>=
res
->
tupArrSize
)
{
/* grow the array */
res
->
tupArrSize
+=
TUPARR_GROW_BY
;
/*
* we can use realloc because shallow copying of the structure is
* Try to grow the array.
*
* We can use realloc because shallow copying of the structure is
* okay. Note that the first time through, res->tuples is NULL.
* realloc is supposed to do the right thing in that case. Also
* note that the positions beyond res->ntups are garbage, not
* realloc is supposed to do the right thing in that case. Also,
* on failure realloc is supposed to return NULL without damaging
* the existing allocation.
* Note that the positions beyond res->ntups are garbage, not
* necessarily NULL.
*/
res
->
tuples
=
(
PGresAttValue
**
)
realloc
(
res
->
tuples
,
res
->
tupArrSize
*
sizeof
(
PGresAttValue
*
));
int
newSize
=
res
->
tupArrSize
+
TUPARR_GROW_BY
;
PGresAttValue
**
newTuples
=
(
PGresAttValue
**
)
realloc
(
res
->
tuples
,
newSize
*
sizeof
(
PGresAttValue
*
));
if
(
!
newTuples
)
return
FALSE
;
/* realloc failed */
res
->
tupArrSize
=
newSize
;
res
->
tuples
=
newTuples
;
}
res
->
tuples
[
res
->
ntups
]
=
tup
;
res
->
ntups
++
;
return
TRUE
;
}
...
...
@@ -235,7 +281,6 @@ PQsendQuery(PGconn *conn, const char *query)
/* initialize async result-accumulation state */
conn
->
result
=
NULL
;
conn
->
curTuple
=
NULL
;
conn
->
asyncErrorMessage
[
0
]
=
'\0'
;
/* send the query to the backend; */
/* the frontend-backend protocol uses 'Q' to designate queries */
...
...
@@ -270,10 +315,8 @@ PQconsumeInput(PGconn *conn)
* application wants to get rid of a read-select condition. Note that
* we will NOT block waiting for more input.
*/
if
(
pqReadData
(
conn
)
<
0
)
{
strcpy
(
conn
->
asyncErrorMessage
,
conn
->
errorMessage
);
if
(
pqReadData
(
conn
)
<
0
)
return
0
;
}
/* Parsing of the data waits till later. */
return
1
;
}
...
...
@@ -360,16 +403,13 @@ parseInput(PGconn *conn)
conn
->
asyncStatus
=
PGASYNC_READY
;
break
;
case
'E'
:
/* error return */
if
(
pqGets
(
conn
->
asyncE
rrorMessage
,
ERROR_MSG_LENGTH
,
conn
))
if
(
pqGets
(
conn
->
e
rrorMessage
,
ERROR_MSG_LENGTH
,
conn
))
return
;
/* delete any partially constructed result */
pqClearAsyncResult
(
conn
);
/*
* we leave result NULL while setting
* asyncStatus=READY; this signals an error condition
* to PQgetResult.
*/
/* and build an error result holding the error message */
conn
->
result
=
PQmakeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
conn
->
asyncStatus
=
PGASYNC_READY
;
break
;
case
'Z'
:
/* backend is ready for new query */
...
...
@@ -470,15 +510,18 @@ parseInput(PGconn *conn)
conn
->
asyncStatus
=
PGASYNC_COPY_OUT
;
break
;
default:
sprintf
(
conn
->
asyncE
rrorMessage
,
sprintf
(
conn
->
e
rrorMessage
,
"unknown protocol character '%c' read from backend. "
"(The protocol character is the first character the "
"backend sends in response to a query it receives).
\n
"
,
"backend sends in response to a query it receives).
\n
"
,
id
);
/* Discard the unexpected message; good idea?? */
conn
->
inStart
=
conn
->
inEnd
;
/* delete any partially constructed result */
pqClearAsyncResult
(
conn
);
/* and build an error result holding the error message */
conn
->
result
=
PQmakeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
conn
->
asyncStatus
=
PGASYNC_READY
;
return
;
}
/* switch on protocol character */
...
...
@@ -565,7 +608,7 @@ getRowDescriptions(PGconn *conn)
/*
* parseInput subroutine to read a 'B' or 'D' (row data) message.
* We add another tuple to the existing PGresult structure.
* Returns: 0 if completed message, EOF if not enough data yet.
* Returns: 0 if completed message, EOF if
error or
not enough data yet.
*
* Note that if we run out of data, we have to suspend and reprocess
* the message after more data is received. We keep a partially constructed
...
...
@@ -593,6 +636,8 @@ getAnotherTuple(PGconn *conn, int binary)
{
conn
->
curTuple
=
(
PGresAttValue
*
)
malloc
(
nfields
*
sizeof
(
PGresAttValue
));
if
(
conn
->
curTuple
==
NULL
)
goto
outOfMemory
;
MemSet
((
char
*
)
conn
->
curTuple
,
0
,
nfields
*
sizeof
(
PGresAttValue
));
}
tup
=
conn
->
curTuple
;
...
...
@@ -601,9 +646,11 @@ getAnotherTuple(PGconn *conn, int binary)
nbytes
=
(
nfields
+
BYTELEN
-
1
)
/
BYTELEN
;
if
(
nbytes
>=
MAX_FIELDS
)
{
sprintf
(
conn
->
asyncErrorMessage
,
"getAnotherTuple() -- null-values bitmap is too large
\n
"
);
/* Replace partially constructed result with an error result */
pqClearAsyncResult
(
conn
);
sprintf
(
conn
->
errorMessage
,
"getAnotherTuple() -- null-values bitmap is too large
\n
"
);
conn
->
result
=
PQmakeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
conn
->
asyncStatus
=
PGASYNC_READY
;
/* Discard the broken message */
conn
->
inStart
=
conn
->
inEnd
;
...
...
@@ -624,7 +671,11 @@ getAnotherTuple(PGconn *conn, int binary)
{
/* if the field value is absent, make it a null string */
if
(
tup
[
i
].
value
==
NULL
)
{
tup
[
i
].
value
=
strdup
(
""
);
if
(
tup
[
i
].
value
==
NULL
)
goto
outOfMemory
;
}
tup
[
i
].
len
=
NULL_LEN
;
}
else
...
...
@@ -637,7 +688,11 @@ getAnotherTuple(PGconn *conn, int binary)
if
(
vlen
<
0
)
vlen
=
0
;
if
(
tup
[
i
].
value
==
NULL
)
{
tup
[
i
].
value
=
(
char
*
)
malloc
(
vlen
+
1
);
if
(
tup
[
i
].
value
==
NULL
)
goto
outOfMemory
;
}
tup
[
i
].
len
=
vlen
;
/* read in the value */
if
(
vlen
>
0
)
...
...
@@ -659,10 +714,28 @@ getAnotherTuple(PGconn *conn, int binary)
}
/* Success! Store the completed tuple in the result */
addTuple
(
conn
->
result
,
tup
);
if
(
!
addTuple
(
conn
->
result
,
tup
))
{
/* Oops, not enough memory to add the tuple to conn->result,
* so must free it ourselves...
*/
freeTuple
(
tup
,
nfields
);
goto
outOfMemory
;
}
/* and reset for a new message */
conn
->
curTuple
=
NULL
;
return
0
;
outOfMemory:
/* Replace partially constructed result with an error result */
pqClearAsyncResult
(
conn
);
sprintf
(
conn
->
errorMessage
,
"getAnotherTuple() -- out of memory for result
\n
"
);
conn
->
result
=
PQmakeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
conn
->
asyncStatus
=
PGASYNC_READY
;
/* Discard the failed message --- good idea? */
conn
->
inStart
=
conn
->
inEnd
;
return
EOF
;
}
...
...
@@ -725,19 +798,26 @@ PQgetResult(PGconn *conn)
res
=
NULL
;
/* query is complete */
break
;
case
PGASYNC_READY
:
/*
* conn->result is the PGresult to return, or possibly NULL
* indicating an error. conn->asyncErrorMessage holds the
* errorMessage to return. (We keep it stashed there so that
* other user calls can't overwrite it prematurely.)
* conn->result is the PGresult to return. If it is NULL
* (which probably shouldn't happen) we assume there is
* an appropriate error message in conn->errorMessage.
*/
res
=
conn
->
result
;
conn
->
result
=
NULL
;
/* handing over ownership to caller */
conn
->
result
=
NULL
;
/* handing over ownership to caller */
conn
->
curTuple
=
NULL
;
/* just in case */
if
(
!
res
)
{
res
=
PQmakeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
strcpy
(
conn
->
errorMessage
,
conn
->
asyncErrorMessage
);
}
else
{
/* Make sure PQerrorMessage agrees with result; it could be
* that we have done other operations that changed
* errorMessage since the result's error message was saved.
*/
strcpy
(
conn
->
errorMessage
,
PQresultErrorMessage
(
res
));
}
/* Set the state back to BUSY, allowing parsing to proceed. */
conn
->
asyncStatus
=
PGASYNC_BUSY
;
break
;
...
...
@@ -763,11 +843,12 @@ PQgetResult(PGconn *conn)
* PQexec
* send a query to the backend and package up the result in a PGresult
*
* if the query failed, return NULL, conn->errorMessage is set to
* a relevant message
* if query is successful, a new PGresult is returned
* the user is responsible for freeing that structure when done with it
*
* If the query was not even sent, return NULL; conn->errorMessage is set to
* a relevant message.
* If the query was sent, a new PGresult is returned (which could indicate
* either success or failure).
* The user is responsible for freeing the PGresult via PQclear()
* when done with it.
*/
PGresult
*
...
...
@@ -1312,6 +1393,14 @@ PQresultStatus(PGresult *res)
return
res
->
resultStatus
;
}
const
char
*
PQresultErrorMessage
(
PGresult
*
res
)
{
if
(
!
res
||
!
res
->
errMsg
)
return
""
;
return
res
->
errMsg
;
}
int
PQntuples
(
PGresult
*
res
)
{
...
...
src/interfaces/libpq/fe-lobj.c
View file @
6428074e
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.1
6 1998/09/01 04:40:07 momjian
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.1
7 1998/10/01 01:40:22 tgl
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -76,7 +76,10 @@ lo_open(PGconn *conn, Oid lobjId, int mode)
return
fd
;
}
else
{
PQclear
(
res
);
return
-
1
;
}
}
/*
...
...
@@ -111,7 +114,10 @@ lo_close(PGconn *conn, int fd)
return
retval
;
}
else
{
PQclear
(
res
);
return
-
1
;
}
}
/*
...
...
@@ -151,7 +157,10 @@ lo_read(PGconn *conn, int fd, char *buf, int len)
return
result_len
;
}
else
{
PQclear
(
res
);
return
-
1
;
}
}
/*
...
...
@@ -192,7 +201,10 @@ lo_write(PGconn *conn, int fd, char *buf, int len)
return
retval
;
}
else
{
PQclear
(
res
);
return
-
1
;
}
}
/*
...
...
@@ -236,7 +248,10 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
return
retval
;
}
else
{
PQclear
(
res
);
return
-
1
;
}
}
/*
...
...
@@ -273,7 +288,10 @@ lo_creat(PGconn *conn, int mode)
return
(
Oid
)
retval
;
}
else
{
PQclear
(
res
);
return
InvalidOid
;
}
}
...
...
@@ -309,7 +327,10 @@ lo_tell(PGconn *conn, int fd)
return
retval
;
}
else
{
PQclear
(
res
);
return
-
1
;
}
}
/*
...
...
@@ -344,7 +365,10 @@ lo_unlink(PGconn *conn, Oid lobjId)
return
retval
;
}
else
{
PQclear
(
res
);
return
-
1
;
}
}
/*
...
...
src/interfaces/libpq/libpq-fe.h
View file @
6428074e
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: libpq-fe.h,v 1.4
3 1998/09/18 16:46:06 momjian
Exp $
* $Id: libpq-fe.h,v 1.4
4 1998/10/01 01:40:23 tgl
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -67,6 +67,8 @@ extern "C"
/* PGnotify represents the occurrence of a NOTIFY message.
* Ideally this would be an opaque typedef, but it's so simple that it's
* unlikely to change.
* NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's,
* whereas in earlier versions it was always your own backend's PID.
*/
typedef
struct
pgNotify
{
...
...
@@ -78,7 +80,7 @@ extern "C"
/* PQnoticeProcessor is the function type for the notice-message callback.
*/
typedef
void
(
*
PQnoticeProcessor
)
(
void
*
arg
,
const
char
*
message
);
typedef
void
(
*
PQnoticeProcessor
)
(
void
*
arg
,
const
char
*
message
);
/* Print options for PQprint() */
...
...
@@ -219,15 +221,16 @@ typedef void (*PQnoticeProcessor) (void * arg, const char * message);
* use
*/
extern
PGresult
*
PQfn
(
PGconn
*
conn
,
int
fnid
,
int
*
result_buf
,
int
*
result_len
,
int
result_is_int
,
PQArgBlock
*
args
,
int
nargs
);
int
fnid
,
int
*
result_buf
,
int
*
result_len
,
int
result_is_int
,
PQArgBlock
*
args
,
int
nargs
);
/* Accessor functions for PGresult objects */
extern
ExecStatusType
PQresultStatus
(
PGresult
*
res
);
extern
const
char
*
PQresultErrorMessage
(
PGresult
*
res
);
extern
int
PQntuples
(
PGresult
*
res
);
extern
int
PQnfields
(
PGresult
*
res
);
extern
int
PQbinaryTuples
(
PGresult
*
res
);
...
...
@@ -246,35 +249,39 @@ typedef void (*PQnoticeProcessor) (void * arg, const char * message);
/* Delete a PGresult */
extern
void
PQclear
(
PGresult
*
res
);
/* Make an empty PGresult with given status (some apps find this useful) */
/* Make an empty PGresult with given status (some apps find this useful).
* If conn is not NULL and status indicates an error, the conn's
* errorMessage is copied.
*/
extern
PGresult
*
PQmakeEmptyPGresult
(
PGconn
*
conn
,
ExecStatusType
status
);
/* === in fe-print.c === */
extern
void
PQprint
(
FILE
*
fout
,
/* output stream */
PGresult
*
res
,
PQprintOpt
*
ps
);
/* option structure */
extern
void
PQprint
(
FILE
*
fout
,
/* output stream */
PGresult
*
res
,
PQprintOpt
*
ps
);
/* option structure */
/*
* PQdisplayTuples() is a better version of PQprintTuples(), but both
* are obsoleted by PQprint().
*/
extern
void
PQdisplayTuples
(
PGresult
*
res
,
FILE
*
fp
,
/* where to send the
* output */
int
fillAlign
,
/* pad the fields with
* spaces */
const
char
*
fieldSep
,
/* field separator */
int
printHeader
,
/* display headers? */
int
quiet
);
FILE
*
fp
,
/* where to send the
* output */
int
fillAlign
,
/* pad the fields with
* spaces */
const
char
*
fieldSep
,
/* field separator */
int
printHeader
,
/* display headers? */
int
quiet
);
extern
void
PQprintTuples
(
PGresult
*
res
,
FILE
*
fout
,
/* output stream */
int
printAttName
,
/* print attribute names
* or not */
int
terseOutput
,
/* delimiter bars or
* not? */
int
width
);
/* width of column, if
* 0, use variable width */
FILE
*
fout
,
/* output stream */
int
printAttName
,
/* print attribute names
* or not */
int
terseOutput
,
/* delimiter bars or
* not? */
int
width
);
/* width of column, if
* 0, use variable width */
#ifdef MULTIBYTE
extern
int
PQmblen
(
unsigned
char
*
s
);
...
...
src/interfaces/libpq/libpq-int.h
View file @
6428074e
...
...
@@ -11,7 +11,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: libpq-int.h,v 1.
3 1998/09/03 02:10:53 momjian
Exp $
* $Id: libpq-int.h,v 1.
4 1998/10/01 01:40:25 tgl
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -78,7 +78,7 @@
char
*
value
;
/* actual value */
}
PGresAttValue
;
struct
pg_result
struct
pg_result
{
int
ntups
;
int
numAttributes
;
...
...
@@ -91,7 +91,15 @@
* last insert query */
int
binary
;
/* binary tuple values if binary == 1,
* otherwise ASCII */
/* NOTE: conn is kept here only for the temporary convenience of
* applications that rely on it being here. It will go away in a
* future release, because relying on it is a bad idea --- what if
* the PGresult has outlived the PGconn? About the only thing it was
* really good for was fetching the errorMessage, and we stash that
* here now anyway.
*/
PGconn
*
conn
;
/* connection we did the query on */
char
*
errMsg
;
/* error message, or NULL if no error */
};
/* PGAsyncStatusType defines the state of the query-execution state machine */
...
...
@@ -174,12 +182,8 @@
PGresult
*
result
;
/* result being constructed */
PGresAttValue
*
curTuple
;
/* tuple currently being read */
/* Message space. Placed last for code-size reasons.
* errorMessage is the message last returned to the application.
* When asyncStatus=READY, asyncErrorMessage is the pending message
* that will be put in errorMessage by PQgetResult. */
/* Message space. Placed last for code-size reasons. */
char
errorMessage
[
ERROR_MSG_LENGTH
];
char
asyncErrorMessage
[
ERROR_MSG_LENGTH
];
};
/* ----------------
...
...
@@ -197,6 +201,7 @@ extern int pqPacketSend(PGconn *conn, const char *buf, size_t len);
/* === in fe-exec.c === */
extern
void
pqSetResultError
(
PGresult
*
res
,
const
char
*
msg
);
extern
void
pqClearAsyncResult
(
PGconn
*
conn
);
/* === in fe-misc.c === */
...
...
src/interfaces/libpq/libpqdll.def
View file @
6428074e
...
...
@@ -63,3 +63,4 @@ EXPORTS
lo_unlink @ 60
lo_import @ 61
lo_export @ 62
PQresultErrorMessage @ 63
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment