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
8fb0ac88
Commit
8fb0ac88
authored
Dec 31, 1996
by
Bryan Henderson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make error messages more explicit, PQtrace() output more readable.
parent
e2da92f1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
186 additions
and
138 deletions
+186
-138
src/interfaces/libpq/fe-exec.c
src/interfaces/libpq/fe-exec.c
+171
-129
src/interfaces/libpq/fe-misc.c
src/interfaces/libpq/fe-misc.c
+15
-9
No files found.
src/interfaces/libpq/fe-exec.c
View file @
8fb0ac88
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.2
5 1996/12/28 01:57:13 momjian
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.2
6 1996/12/31 07:29:15 bryanh
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -348,6 +348,170 @@ makePGresult_badResponse_return:
...
@@ -348,6 +348,170 @@ makePGresult_badResponse_return:
}
}
/*
* Assuming that we just sent a query to the backend, read the backend's
* response from stream <pfin> and respond accordingly.
*
* If <pfdebug> is non-null, write to that stream whatever we receive
* (it's a debugging trace).
*
* Return as <result> a pointer to a proper final PGresult structure,
* newly allocated, for the query based on the response we get. If the
* response we get indicates that the query didn't execute, return a
* null pointer and don't allocate any space, but also place a text
* string explaining the problem at <*reason>.
*/
static
void
process_response_from_backend
(
FILE
*
pfin
,
FILE
*
pfout
,
FILE
*
pfdebug
,
PGconn
*
conn
,
PGresult
**
result_p
,
char
*
const
reason
)
{
char
id
;
/* The protocol character received from the backend. The protocol
character is the first character in the backend's response to our
query. It defines the nature of the response.
*/
PGnotify
*
newNotify
;
bool
done
;
/* We're all done with the query and ready to return the result. */
int
emptiesSent
;
/* Number of empty queries we have sent in order to flush out multiple
responses, less the number of corresponding responses we have
received.
*/
char
cmdStatus
[
MAX_MESSAGE_LEN
];
char
pname
[
MAX_MESSAGE_LEN
];
/* portal name */
/* loop because multiple messages, especially NOTICES,
can come back from the backend. NOTICES are output directly to stderr
*/
emptiesSent
=
0
;
/* No empty queries sent yet */
pname
[
0
]
=
'\0'
;
done
=
false
;
/* initial value */
while
(
!
done
)
{
/* read the result id */
id
=
pqGetc
(
pfin
,
pfdebug
);
if
(
id
==
EOF
)
{
/* hmm, no response from the backend-end, that's bad */
(
void
)
sprintf
(
reason
,
"PQexec() -- Request was sent to backend, but backend "
"closed the channel before "
"responding. This probably means the backend "
"terminated abnormally before or while processing "
"the request.
\n
"
);
conn
->
status
=
CONNECTION_BAD
;
/* No more connection to backend */
*
result_p
=
(
PGresult
*
)
NULL
;
done
=
true
;
}
else
{
switch
(
id
)
{
case
'A'
:
newNotify
=
(
PGnotify
*
)
malloc
(
sizeof
(
PGnotify
));
pqGetInt
(
&
(
newNotify
->
be_pid
),
4
,
pfin
,
pfdebug
);
pqGets
(
newNotify
->
relname
,
NAMEDATALEN
,
pfin
,
pfdebug
);
DLAddTail
(
conn
->
notifyList
,
DLNewElem
(
newNotify
));
/* async messages are piggy'ed back on other messages,
so we stay in the while loop for other messages */
break
;
case
'C'
:
/* portal query command, no rows returned */
if
(
pqGets
(
cmdStatus
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
reason
,
"PQexec() -- query command completed, "
"but return message from backend cannot be read."
);
*
result_p
=
(
PGresult
*
)
NULL
;
done
=
true
;
}
else
{
/*
// since backend may produce more than one result for some
// commands need to poll until clear
// send an empty query down, and keep reading out of the pipe
// until an 'I' is received.
*/
pqPuts
(
"Q "
,
pfout
,
pfdebug
);
/* send an empty query */
/*
* Increment a flag and process messages in the usual way because
* there may be async notifications pending. DZ - 31-8-1996
*/
emptiesSent
++
;
}
break
;
case
'E'
:
/* error return */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
(
void
)
sprintf
(
reason
,
"PQexec() -- error return detected from backend, "
"but attempt to read the error message failed."
);
}
*
result_p
=
(
PGresult
*
)
NULL
;
done
=
true
;
break
;
case
'I'
:
{
/* empty query */
/* read and throw away the closing '\0' */
int
c
;
if
((
c
=
pqGetc
(
pfin
,
pfdebug
))
!=
'\0'
)
{
fprintf
(
stderr
,
"error!, unexpected character %c following 'I'
\n
"
,
c
);
}
if
(
emptiesSent
)
{
if
(
--
emptiesSent
==
0
)
{
/* is this the last one? */
/*
* If this is the result of a portal query command set the
* command status and message accordingly. DZ - 31-8-1996
*/
*
result_p
=
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
strncpy
((
*
result_p
)
->
cmdStatus
,
cmdStatus
,
CMDSTATUS_LEN
-
1
);
done
=
true
;
}
}
else
{
*
result_p
=
makeEmptyPGresult
(
conn
,
PGRES_EMPTY_QUERY
);
done
=
true
;
}
}
break
;
case
'N'
:
/* notices from the backend */
if
(
pqGets
(
reason
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
reason
,
"PQexec() -- Notice detected from backend, "
"but attempt to read the notice failed."
);
*
result_p
=
(
PGresult
*
)
NULL
;
done
=
true
;
}
else
/* Should we really be doing this? These notices are not important
enough for us to presume to put them on stderr. Maybe the caller
should decide whether to put them on stderr or not. BJH 96.12.27
*/
fprintf
(
stderr
,
"%s"
,
reason
);
break
;
case
'P'
:
/* synchronous (normal) portal */
pqGets
(
pname
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
);
/* read in portal name*/
break
;
case
'T'
:
/* actual row results: */
*
result_p
=
makePGresult
(
conn
,
pname
);
done
=
true
;
break
;
case
'D'
:
/* copy command began successfully */
*
result_p
=
makeEmptyPGresult
(
conn
,
PGRES_COPY_IN
);
done
=
true
;
break
;
case
'B'
:
/* copy command began successfully */
*
result_p
=
makeEmptyPGresult
(
conn
,
PGRES_COPY_OUT
);
done
=
true
;
break
;
default:
sprintf
(
reason
,
"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
"
,
id
);
*
result_p
=
(
PGresult
*
)
NULL
;
done
=
true
;
}
/* switch on protocol character */
}
/* if character was received */
}
/* while not done */
}
/*
/*
* PQexec
* PQexec
...
@@ -364,16 +528,7 @@ PGresult*
...
@@ -364,16 +528,7 @@ PGresult*
PQexec
(
PGconn
*
conn
,
const
char
*
query
)
PQexec
(
PGconn
*
conn
,
const
char
*
query
)
{
{
PGresult
*
result
;
PGresult
*
result
;
int
id
;
char
buffer
[
MAX_MESSAGE_LEN
];
char
buffer
[
MAX_MESSAGE_LEN
];
char
cmdStatus
[
MAX_MESSAGE_LEN
];
char
pname
[
MAX_MESSAGE_LEN
];
/* portal name */
PGnotify
*
newNotify
;
FILE
*
pfin
,
*
pfout
,
*
pfdebug
;
static
int
emptiesPending
=
0
;
bool
emptySent
=
false
;
pname
[
0
]
=
'\0'
;
if
(
!
conn
)
return
NULL
;
if
(
!
conn
)
return
NULL
;
if
(
!
query
)
{
if
(
!
query
)
{
...
@@ -381,10 +536,6 @@ PQexec(PGconn* conn, const char* query)
...
@@ -381,10 +536,6 @@ PQexec(PGconn* conn, const char* query)
return
NULL
;
return
NULL
;
}
}
pfin
=
conn
->
Pfin
;
pfout
=
conn
->
Pfout
;
pfdebug
=
conn
->
Pfdebug
;
/*clear the error string */
/*clear the error string */
conn
->
errorMessage
[
0
]
=
'\0'
;
conn
->
errorMessage
[
0
]
=
'\0'
;
...
@@ -406,129 +557,20 @@ PQexec(PGconn* conn, const char* query)
...
@@ -406,129 +557,20 @@ PQexec(PGconn* conn, const char* query)
sprintf
(
buffer
,
"Q%s"
,
query
);
sprintf
(
buffer
,
"Q%s"
,
query
);
/* send the query to the backend; */
/* send the query to the backend; */
if
(
pqPuts
(
buffer
,
pfout
,
p
fdebug
)
==
1
)
{
if
(
pqPuts
(
buffer
,
conn
->
Pfout
,
conn
->
P
fdebug
)
==
1
)
{
(
void
)
sprintf
(
conn
->
errorMessage
,
(
void
)
sprintf
(
conn
->
errorMessage
,
"PQexec() -- while sending query: %s
\n
"
"PQexec() -- while sending query: %s
\n
"
"-- fprintf to Pfout failed: errno=%d
\n
%s
\n
"
,
"-- fprintf to Pfout failed: errno=%d
\n
%s
\n
"
,
query
,
errno
,
strerror
(
errno
));
query
,
errno
,
strerror
(
errno
));
return
NULL
;
return
NULL
;
}
}
/* loop forever because multiple messages, especially NOTICES,
process_response_from_backend
(
conn
->
Pfin
,
conn
->
Pfout
,
conn
->
Pfdebug
,
conn
,
can come back from the backend
&
result
,
conn
->
errorMessage
);
NOTICES are output directly to stderr
return
(
result
);
*/
}
while
(
1
)
{
/* read the result id */
id
=
pqGetc
(
pfin
,
pfdebug
);
if
(
id
==
EOF
)
{
/* hmm, no response from the backend-end, that's bad */
(
void
)
sprintf
(
conn
->
errorMessage
,
"PQexec() -- Request was sent to backend, but backend "
"closed the channel before "
"responding. This probably means the backend "
"terminated abnormally before or while processing "
"the request.
\n
"
);
conn
->
status
=
CONNECTION_BAD
;
/* No more connection to backend */
return
(
PGresult
*
)
NULL
;
}
switch
(
id
)
{
case
'A'
:
newNotify
=
(
PGnotify
*
)
malloc
(
sizeof
(
PGnotify
));
pqGetInt
(
&
(
newNotify
->
be_pid
),
4
,
pfin
,
pfdebug
);
pqGets
(
newNotify
->
relname
,
NAMEDATALEN
,
pfin
,
pfdebug
);
DLAddTail
(
conn
->
notifyList
,
DLNewElem
(
newNotify
));
/* async messages are piggy'ed back on other messages,
so we stay in the while loop for other messages */
break
;
case
'C'
:
/* portal query command, no rows returned */
if
(
pqGets
(
cmdStatus
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
"PQexec() -- query command completed, "
"but return message from backend cannot be read."
);
return
(
PGresult
*
)
NULL
;
}
else
{
/*
// since backend may produce more than one result for some commands
// need to poll until clear
// send an empty query down, and keep reading out of the pipe
// until an 'I' is received.
*/
pqPuts
(
"Q"
,
pfout
,
pfdebug
);
/* send an empty query */
/*
* Increment a flag and process messages in the usual way because
* there may be async notifications pending. DZ - 31-8-1996
*/
emptiesPending
++
;
emptySent
=
true
;
}
break
;
case
'E'
:
/* error return */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
(
void
)
sprintf
(
conn
->
errorMessage
,
"PQexec() -- error return detected from backend, "
"but attempt to read the error message failed."
);
}
return
(
PGresult
*
)
NULL
;
break
;
case
'I'
:
/* empty query */
/* read the throw away the closing '\0' */
{
int
c
;
if
((
c
=
pqGetc
(
pfin
,
pfdebug
))
!=
'\0'
)
{
fprintf
(
stderr
,
"error!, unexpected character %c following 'I'
\n
"
,
c
);
}
if
(
emptiesPending
)
{
if
(
--
emptiesPending
==
0
&&
emptySent
)
{
/* is this the last one? */
/*
* If this is the result of a portal query command set the
* command status and message accordingly. DZ - 31-8-1996
*/
result
=
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
strncpy
(
result
->
cmdStatus
,
cmdStatus
,
CMDSTATUS_LEN
-
1
);
return
result
;
}
}
else
{
result
=
makeEmptyPGresult
(
conn
,
PGRES_EMPTY_QUERY
);
return
result
;
}
}
break
;
case
'N'
:
/* notices from the backend */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
"PQexec() -- Notice detected from backend, "
"but attempt to read the notice failed."
);
return
(
PGresult
*
)
NULL
;
}
else
fprintf
(
stderr
,
"%s"
,
conn
->
errorMessage
);
break
;
case
'P'
:
/* synchronous (normal) portal */
pqGets
(
pname
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
);
/* read in portal name*/
break
;
case
'T'
:
/* actual row results: */
return
makePGresult
(
conn
,
pname
);
break
;
case
'D'
:
/* copy command began successfully */
return
makeEmptyPGresult
(
conn
,
PGRES_COPY_IN
);
break
;
case
'B'
:
/* copy command began successfully */
return
makeEmptyPGresult
(
conn
,
PGRES_COPY_OUT
);
break
;
default:
sprintf
(
conn
->
errorMessage
,
"unknown protocol character %c read from backend
\n
"
,
id
);
return
(
PGresult
*
)
NULL
;
}
/* switch */
}
/* while (1)*/
}
/*
/*
* PQnotifies
* PQnotifies
...
...
src/interfaces/libpq/fe-misc.c
View file @
8fb0ac88
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.
3 1996/11/03 07:14:32 scrappy
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.
4 1996/12/31 07:29:17 bryanh
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -35,7 +35,7 @@ pqGetc(FILE* fin, FILE* debug)
...
@@ -35,7 +35,7 @@ pqGetc(FILE* fin, FILE* debug)
c
=
getc
(
fin
);
c
=
getc
(
fin
);
if
(
debug
&&
c
!=
EOF
)
if
(
debug
&&
c
!=
EOF
)
putc
(
c
,
debug
);
fprintf
(
debug
,
"From backend> %c
\n
"
,
c
);
return
c
;
return
c
;
}
}
...
@@ -52,6 +52,7 @@ pqPutnchar(const char* s, int len, FILE *f, FILE *debug)
...
@@ -52,6 +52,7 @@ pqPutnchar(const char* s, int len, FILE *f, FILE *debug)
if
(
f
==
NULL
)
if
(
f
==
NULL
)
return
1
;
return
1
;
if
(
debug
)
fputs
(
"To backend>"
,
debug
);
while
(
len
--
)
{
while
(
len
--
)
{
status
=
fputc
(
*
s
,
f
);
status
=
fputc
(
*
s
,
f
);
if
(
debug
)
if
(
debug
)
...
@@ -60,6 +61,7 @@ pqPutnchar(const char* s, int len, FILE *f, FILE *debug)
...
@@ -60,6 +61,7 @@ pqPutnchar(const char* s, int len, FILE *f, FILE *debug)
if
(
status
==
EOF
)
if
(
status
==
EOF
)
return
1
;
return
1
;
}
}
if
(
debug
)
fputc
(
'\n'
,
debug
);
return
0
;
return
0
;
}
}
...
@@ -79,7 +81,7 @@ pqGetnchar(char* s, int len, FILE *f, FILE *debug)
...
@@ -79,7 +81,7 @@ pqGetnchar(char* s, int len, FILE *f, FILE *debug)
*
s
=
'\0'
;
*
s
=
'\0'
;
if
(
debug
)
{
if
(
debug
)
{
fp
uts
(
s
,
debug
);
fp
rintf
(
debug
,
"From backend> %s
\n
"
,
s
);
}
}
return
0
;
return
0
;
}
}
...
@@ -100,7 +102,7 @@ pqGets(char* s, int len, FILE *f, FILE *debug)
...
@@ -100,7 +102,7 @@ pqGets(char* s, int len, FILE *f, FILE *debug)
*
s
=
'\0'
;
*
s
=
'\0'
;
if
(
debug
)
{
if
(
debug
)
{
fp
uts
(
s
,
debug
);
fp
rintf
(
debug
,
"From backend> %s
\n
"
,
s
);
}
}
return
0
;
return
0
;
}
}
...
@@ -114,22 +116,24 @@ pqGets(char* s, int len, FILE *f, FILE *debug)
...
@@ -114,22 +116,24 @@ pqGets(char* s, int len, FILE *f, FILE *debug)
returns 0 if successful, 1 otherwise
returns 0 if successful, 1 otherwise
*/
*/
int
int
pqPutInt
(
int
i
,
int
bytes
,
FILE
*
f
,
FILE
*
debug
)
pqPutInt
(
const
int
integer
,
int
bytes
,
FILE
*
f
,
FILE
*
debug
)
{
{
int
i
;
int
status
;
int
status
;
i
=
integer
;
if
(
bytes
>
4
)
if
(
bytes
>
4
)
bytes
=
4
;
bytes
=
4
;
while
(
bytes
--
)
{
while
(
bytes
--
)
{
status
=
fputc
(
i
&
0xff
,
f
);
status
=
fputc
(
i
&
0xff
,
f
);
if
(
debug
)
fputc
(
i
&
0xff
,
debug
);
i
>>=
8
;
i
>>=
8
;
if
(
status
==
EOF
)
{
if
(
status
==
EOF
)
{
return
1
;
return
1
;
}
}
}
}
if
(
debug
)
fprintf
(
debug
,
"To backend (#)> %d
\n
"
,
integer
);
return
0
;
return
0
;
}
}
...
@@ -163,7 +167,7 @@ pqGetInt(int* result, int bytes, FILE* f, FILE *debug)
...
@@ -163,7 +167,7 @@ pqGetInt(int* result, int bytes, FILE* f, FILE *debug)
*
result
=
n
;
*
result
=
n
;
if
(
debug
)
if
(
debug
)
fprintf
(
debug
,
"
%d
"
,
*
result
);
fprintf
(
debug
,
"
From backend (#)> %d
\n
"
,
*
result
);
return
0
;
return
0
;
}
}
...
@@ -181,7 +185,7 @@ pqPuts(const char* s, FILE *f, FILE *debug)
...
@@ -181,7 +185,7 @@ pqPuts(const char* s, FILE *f, FILE *debug)
fflush
(
f
);
fflush
(
f
);
if
(
debug
)
{
if
(
debug
)
{
fp
uts
(
s
,
debug
);
fp
rintf
(
debug
,
"To backend> %s
\n
"
,
s
);
}
}
return
0
;
return
0
;
}
}
...
@@ -195,3 +199,5 @@ pqFlush(FILE *f, FILE *debug)
...
@@ -195,3 +199,5 @@ pqFlush(FILE *f, FILE *debug)
if
(
debug
)
if
(
debug
)
fflush
(
debug
);
fflush
(
debug
);
}
}
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