Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
6428074e
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6428074e
编写于
10月 01, 1998
作者:
T
Tom Lane
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update libpq to store an error message in PGresult, per pgsq-interfaces discussion of 21-Sep.
上级
502769d0
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
205 addition
and
79 deletion
+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
未找到文件。
src/interfaces/libpq/fe-connect.c
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
6428074e
...
...
@@ -63,3 +63,4 @@ EXPORTS
lo_unlink @ 60
lo_import @ 61
lo_export @ 62
PQresultErrorMessage @ 63
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录