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
255363f8
Commit
255363f8
authored
Dec 13, 1996
by
Bryan Henderson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Clean up. Get rid of tabs and overly long lines.
parent
ea8b5196
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
714 additions
and
672 deletions
+714
-672
src/interfaces/libpq/fe-exec.c
src/interfaces/libpq/fe-exec.c
+714
-672
No files found.
src/interfaces/libpq/fe-exec.c
View file @
255363f8
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.
19 1996/11/20 22:35:19 momjian
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.
20 1996/12/13 09:25:08 bryanh
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -32,7 +32,7 @@ struct winsize {
...
@@ -32,7 +32,7 @@ struct winsize {
}
screen_size
;
}
screen_size
;
#endif
#endif
/* the
tuples array in a PGresGroup has to grow to accommodate the tuple
s */
/* the
rows array in a PGresGroup has to grow to accommodate the row
s */
/* returned. Each time, we grow by this much: */
/* returned. Each time, we grow by this much: */
#define TUPARR_GROW_BY 100
#define TUPARR_GROW_BY 100
...
@@ -64,25 +64,25 @@ PQclear(PGresult* res)
...
@@ -64,25 +64,25 @@ PQclear(PGresult* res)
int
i
,
j
;
int
i
,
j
;
if
(
!
res
)
if
(
!
res
)
return
;
return
;
/* free all the
tuple
s */
/* free all the
row
s */
for
(
i
=
0
;
i
<
res
->
ntups
;
i
++
)
{
for
(
i
=
0
;
i
<
res
->
ntups
;
i
++
)
{
for
(
j
=
0
;
j
<
res
->
numAttributes
;
j
++
)
{
for
(
j
=
0
;
j
<
res
->
numAttributes
;
j
++
)
{
if
(
res
->
tuples
[
i
][
j
].
value
)
if
(
res
->
tuples
[
i
][
j
].
value
)
free
(
res
->
tuples
[
i
][
j
].
value
);
free
(
res
->
tuples
[
i
][
j
].
value
);
}
}
free
(
res
->
tuples
[
i
]);
free
(
res
->
tuples
[
i
]);
}
}
free
(
res
->
tuples
);
free
(
res
->
tuples
);
/* free all the attributes */
/* free all the attributes */
for
(
i
=
0
;
i
<
res
->
numAttributes
;
i
++
)
{
for
(
i
=
0
;
i
<
res
->
numAttributes
;
i
++
)
{
if
(
res
->
attDescs
[
i
].
name
)
if
(
res
->
attDescs
[
i
].
name
)
free
(
res
->
attDescs
[
i
].
name
);
free
(
res
->
attDescs
[
i
].
name
);
}
}
free
(
res
->
attDescs
);
free
(
res
->
attDescs
);
/* free the structure itself */
/* free the structure itself */
free
(
res
);
free
(
res
);
}
}
...
@@ -114,7 +114,7 @@ makeEmptyPGresult(PGconn *conn, ExecStatusType status)
...
@@ -114,7 +114,7 @@ makeEmptyPGresult(PGconn *conn, ExecStatusType status)
/*
/*
* getTuple -
* getTuple -
* get the next
tuple
from the stream
* get the next
row
from the stream
*
*
* the CALLER is responsible from freeing the PGresAttValue returned
* the CALLER is responsible from freeing the PGresAttValue returned
*/
*/
...
@@ -127,9 +127,9 @@ getTuple(PGconn *conn, PGresult* result, int binary)
...
@@ -127,9 +127,9 @@ getTuple(PGconn *conn, PGresult* result, int binary)
int
bitmap_index
=
0
;
int
bitmap_index
=
0
;
int
i
;
int
i
;
int
nbytes
;
/* the number of bytes in bitmap */
int
nbytes
;
/* the number of bytes in bitmap */
char
bmap
;
/* One byte of the bitmap */
char
bmap
;
/* One byte of the bitmap */
int
bitcnt
=
0
;
/* number of bits examined in current byte */
int
bitcnt
=
0
;
/* number of bits examined in current byte */
int
vlen
;
/* length of the current field value */
int
vlen
;
/* length of the current field value */
FILE
*
pfin
=
conn
->
Pfin
;
FILE
*
pfin
=
conn
->
Pfin
;
FILE
*
pfdebug
=
conn
->
Pfdebug
;
FILE
*
pfdebug
=
conn
->
Pfdebug
;
...
@@ -147,7 +147,7 @@ getTuple(PGconn *conn, PGresult* result, int binary)
...
@@ -147,7 +147,7 @@ getTuple(PGconn *conn, PGresult* result, int binary)
if
(
pqGetnchar
(
bitmap
,
nbytes
,
pfin
,
pfdebug
)
==
1
){
if
(
pqGetnchar
(
bitmap
,
nbytes
,
pfin
,
pfdebug
)
==
1
){
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"Error reading null-values bitmap from tuple
data stream
\n
"
);
"Error reading null-values bitmap from row
data stream
\n
"
);
return
NULL
;
return
NULL
;
}
}
...
@@ -155,24 +155,24 @@ getTuple(PGconn *conn, PGresult* result, int binary)
...
@@ -155,24 +155,24 @@ getTuple(PGconn *conn, PGresult* result, int binary)
for
(
i
=
0
;
i
<
nfields
;
i
++
)
{
for
(
i
=
0
;
i
<
nfields
;
i
++
)
{
if
(
!
(
bmap
&
0200
))
{
if
(
!
(
bmap
&
0200
))
{
/* if the field value is absent, make it '\0' */
/* if the field value is absent, make it '\0' */
tup
[
i
].
value
=
(
char
*
)
malloc
(
1
);
tup
[
i
].
value
=
(
char
*
)
malloc
(
1
);
tup
[
i
].
value
[
0
]
=
'\0'
;
tup
[
i
].
value
[
0
]
=
'\0'
;
tup
[
i
].
len
=
NULL_LEN
;
tup
[
i
].
len
=
NULL_LEN
;
}
}
else
{
else
{
/* get the value length (the first four bytes are for length) */
/* get the value length (the first four bytes are for length) */
pqGetInt
(
&
vlen
,
VARHDRSZ
,
pfin
,
pfdebug
);
pqGetInt
(
&
vlen
,
VARHDRSZ
,
pfin
,
pfdebug
);
if
(
binary
==
0
)
{
if
(
binary
==
0
)
{
vlen
=
vlen
-
VARHDRSZ
;
vlen
=
vlen
-
VARHDRSZ
;
}
}
if
(
vlen
<
0
)
if
(
vlen
<
0
)
vlen
=
0
;
vlen
=
0
;
tup
[
i
].
len
=
vlen
;
tup
[
i
].
len
=
vlen
;
tup
[
i
].
value
=
(
char
*
)
malloc
(
vlen
+
1
);
tup
[
i
].
value
=
(
char
*
)
malloc
(
vlen
+
1
);
/* read in the value; */
/* read in the value; */
if
(
vlen
>
0
)
if
(
vlen
>
0
)
pqGetnchar
((
char
*
)(
tup
[
i
].
value
),
vlen
,
pfin
,
pfdebug
);
pqGetnchar
((
char
*
)(
tup
[
i
].
value
),
vlen
,
pfin
,
pfdebug
);
tup
[
i
].
value
[
vlen
]
=
'\0'
;
tup
[
i
].
value
[
vlen
]
=
'\0'
;
}
}
/* get the appropriate bitmap */
/* get the appropriate bitmap */
...
@@ -191,7 +191,7 @@ getTuple(PGconn *conn, PGresult* result, int binary)
...
@@ -191,7 +191,7 @@ getTuple(PGconn *conn, PGresult* result, int binary)
/*
/*
* addTuple
* addTuple
* add a
tuple
to the PGresult structure, growing it if necessary
* add a
row
to the PGresult structure, growing it if necessary
* to accommodate
* to accommodate
*
*
*/
*/
...
@@ -204,11 +204,11 @@ addTuple(PGresult* res, PGresAttValue* tup)
...
@@ -204,11 +204,11 @@ addTuple(PGresult* res, PGresAttValue* tup)
if
(
res
->
ntups
==
0
)
if
(
res
->
ntups
==
0
)
res
->
tuples
=
(
PGresAttValue
**
)
res
->
tuples
=
(
PGresAttValue
**
)
malloc
(
res
->
tupArrSize
*
sizeof
(
PGresAttValue
*
));
malloc
(
res
->
tupArrSize
*
sizeof
(
PGresAttValue
*
));
else
else
/* we can use realloc because shallow copying of the structure is okay */
/* we can use realloc because shallow copying of the structure is okay */
res
->
tuples
=
(
PGresAttValue
**
)
res
->
tuples
=
(
PGresAttValue
**
)
realloc
(
res
->
tuples
,
res
->
tupArrSize
*
sizeof
(
PGresAttValue
*
));
realloc
(
res
->
tuples
,
res
->
tupArrSize
*
sizeof
(
PGresAttValue
*
));
}
}
res
->
tuples
[
res
->
ntups
]
=
tup
;
res
->
tuples
[
res
->
ntups
]
=
tup
;
...
@@ -217,11 +217,11 @@ addTuple(PGresult* res, PGresAttValue* tup)
...
@@ -217,11 +217,11 @@ addTuple(PGresult* res, PGresAttValue* tup)
/*
/*
* PGresult
* PGresult
* fill out the PGresult structure with result
tuple
s from the backend
* fill out the PGresult structure with result
row
s from the backend
* this is called after query has been successfully run and we have
* this is called after query has been successfully run and we have
* a portal name
* a portal name
*
*
* ASSUMPTION: we assume only *1*
tuple
group is returned from the backend
* ASSUMPTION: we assume only *1*
row
group is returned from the backend
*
*
* the CALLER is reponsible for free'ing the new PGresult allocated here
* the CALLER is reponsible for free'ing the new PGresult allocated here
*
*
...
@@ -249,7 +249,7 @@ makePGresult(PGconn* conn, char* pname)
...
@@ -249,7 +249,7 @@ makePGresult(PGconn* conn, char* pname)
/* the next two bytes are the number of fields */
/* the next two bytes are the number of fields */
if
(
pqGetInt
(
&
nfields
,
2
,
pfin
,
pfdebug
)
==
1
)
{
if
(
pqGetInt
(
&
nfields
,
2
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"could not get the number of fields from the 'T' message
\n
"
);
"could not get the number of fields from the 'T' message
\n
"
);
goto
makePGresult_badResponse_return
;
goto
makePGresult_badResponse_return
;
}
}
else
else
...
@@ -267,10 +267,10 @@ makePGresult(PGconn* conn, char* pname)
...
@@ -267,10 +267,10 @@ makePGresult(PGconn* conn, char* pname)
int
adtsize
;
int
adtsize
;
if
(
pqGets
(
typName
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
)
||
if
(
pqGets
(
typName
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
)
||
pqGetInt
(
&
adtid
,
4
,
pfin
,
pfdebug
)
||
pqGetInt
(
&
adtid
,
4
,
pfin
,
pfdebug
)
||
pqGetInt
(
&
adtsize
,
2
,
pfin
,
pfdebug
))
{
pqGetInt
(
&
adtsize
,
2
,
pfin
,
pfdebug
))
{
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"error reading type information from the 'T' message
\n
"
);
"error reading type information from the 'T' message
\n
"
);
goto
makePGresult_badResponse_return
;
goto
makePGresult_badResponse_return
;
}
}
result
->
attDescs
[
i
].
name
=
malloc
(
strlen
(
typName
)
+
1
);
result
->
attDescs
[
i
].
name
=
malloc
(
strlen
(
typName
)
+
1
);
...
@@ -284,50 +284,49 @@ makePGresult(PGconn* conn, char* pname)
...
@@ -284,50 +284,49 @@ makePGresult(PGconn* conn, char* pname)
/* process the data stream until we're finished */
/* process the data stream until we're finished */
while
(
!
done
)
{
while
(
!
done
)
{
switch
(
id
)
{
switch
(
id
)
{
case
'T'
:
/* a new
tuple
group */
case
'T'
:
/* a new
row
group */
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"makePGresult() -- is not equipped to handle multiple tuple groups.
\n
"
);
"makePGresult() -- "
"is not equipped to handle multiple row groups.
\n
"
);
goto
makePGresult_badResponse_return
;
goto
makePGresult_badResponse_return
;
case
'B'
:
/* a
tuple
in binary format */
case
'B'
:
/* a
row
in binary format */
case
'D'
:
/* a
tuple
in ASCII format */
case
'D'
:
/* a
row
in ASCII format */
newTup
=
getTuple
(
conn
,
result
,
(
id
==
'B'
));
newTup
=
getTuple
(
conn
,
result
,
(
id
==
'B'
));
if
(
newTup
==
NULL
)
if
(
newTup
==
NULL
)
goto
makePGresult_badResponse_return
;
goto
makePGresult_badResponse_return
;
addTuple
(
result
,
newTup
);
addTuple
(
result
,
newTup
);
break
;
break
;
/* case 'A':
case
'C'
:
/* end of portal row stream */
sprintf(conn->errorMessage, "Asynchronous portals not supported");
result->resultStatus = PGRES_NONFATAL_ERROR;
return result;
break;
*/
case
'C'
:
/* end of portal tuple stream */
{
{
char
command
[
MAX_MESSAGE_LEN
];
char
command
[
MAX_MESSAGE_LEN
];
pqGets
(
command
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
);
/* read
the
command tag */
pqGets
(
command
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
);
/* read command tag */
done
=
1
;
done
=
1
;
}
}
break
;
break
;
case
'E'
:
/* errors */
case
'E'
:
/* errors */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"Error return detected from backend, but error message cannot be read"
);
"Error return detected from backend, "
"but error message cannot be read"
);
}
}
result
->
resultStatus
=
PGRES_FATAL_ERROR
;
result
->
resultStatus
=
PGRES_FATAL_ERROR
;
return
result
;
return
result
;
break
;
break
;
case
'N'
:
/* notices from the backend */
case
'N'
:
/* notices from the backend */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"Notice return detected from backend, but error message cannot be read"
);
"Notice return detected from backend, "
}
else
"but error message cannot be read"
);
/* XXXX send Notices to stderr for now */
}
else
fprintf
(
stderr
,
"%s
\n
"
,
conn
->
errorMessage
);
/* XXXX send Notices to stderr for now */
fprintf
(
stderr
,
"%s
\n
"
,
conn
->
errorMessage
);
break
;
break
;
default:
/* uh-oh
default:
/* uh-oh
this should never happen but frequently does when the
this should never happen but frequently does when the
backend dumps core */
backend dumps core */
sprintf
(
conn
->
errorMessage
,
"FATAL: unexpected results from the backend, it probably dumped core."
);
sprintf
(
conn
->
errorMessage
,
"FATAL: unrecognized data from the backend. "
"It probably dumped core."
);
fprintf
(
stderr
,
conn
->
errorMessage
);
fprintf
(
stderr
,
conn
->
errorMessage
);
result
->
resultStatus
=
PGRES_FATAL_ERROR
;
result
->
resultStatus
=
PGRES_FATAL_ERROR
;
return
result
;
return
result
;
...
@@ -371,7 +370,7 @@ PQexec(PGconn* conn, const char* query)
...
@@ -371,7 +370,7 @@ PQexec(PGconn* conn, const char* query)
FILE
*
pfin
,
*
pfout
,
*
pfdebug
;
FILE
*
pfin
,
*
pfout
,
*
pfdebug
;
#ifdef PQ_NOTIFY_PATCH
#ifdef PQ_NOTIFY_PATCH
int
isCommand
=
0
;
/* DZ - 31-8-1996 */
int
isCommand
=
0
;
/* DZ - 31-8-1996 */
#endif
#endif
pname
[
0
]
=
'\0'
;
pname
[
0
]
=
'\0'
;
...
@@ -409,9 +408,9 @@ PQexec(PGconn* conn, const char* query)
...
@@ -409,9 +408,9 @@ PQexec(PGconn* conn, const char* query)
/* send the query to the backend; */
/* send the query to the backend; */
if
(
pqPuts
(
buffer
,
pfout
,
pfdebug
)
==
1
)
{
if
(
pqPuts
(
buffer
,
pfout
,
pfdebug
)
==
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
;
}
}
...
@@ -427,7 +426,7 @@ PQexec(PGconn* conn, const char* query)
...
@@ -427,7 +426,7 @@ PQexec(PGconn* conn, const char* query)
if
(
id
==
EOF
)
{
if
(
id
==
EOF
)
{
/* hmm, no response from the backend-end, that's bad */
/* hmm, no response from the backend-end, that's bad */
(
void
)
sprintf
(
conn
->
errorMessage
,
(
void
)
sprintf
(
conn
->
errorMessage
,
"PQexec() -- Request was sent to backend, but backend "
"PQexec() -- Request was sent to backend, but backend "
"closed the channel before "
"closed the channel before "
"responding. This probably means the backend "
"responding. This probably means the backend "
"terminated abnormally before or while processing "
"terminated abnormally before or while processing "
...
@@ -438,30 +437,31 @@ PQexec(PGconn* conn, const char* query)
...
@@ -438,30 +437,31 @@ PQexec(PGconn* conn, const char* query)
switch
(
id
)
{
switch
(
id
)
{
case
'A'
:
case
'A'
:
newNotify
=
(
PGnotify
*
)
malloc
(
sizeof
(
PGnotify
));
newNotify
=
(
PGnotify
*
)
malloc
(
sizeof
(
PGnotify
));
pqGetInt
(
&
(
newNotify
->
be_pid
),
4
,
pfin
,
pfdebug
);
pqGetInt
(
&
(
newNotify
->
be_pid
),
4
,
pfin
,
pfdebug
);
pqGets
(
newNotify
->
relname
,
NAMEDATALEN
,
pfin
,
pfdebug
);
pqGets
(
newNotify
->
relname
,
NAMEDATALEN
,
pfin
,
pfdebug
);
DLAddTail
(
conn
->
notifyList
,
DLNewElem
(
newNotify
));
DLAddTail
(
conn
->
notifyList
,
DLNewElem
(
newNotify
));
/* async messages are piggy'ed back on other messages,
/* async messages are piggy'ed back on other messages,
so we stay in the while loop for other messages */
so we stay in the while loop for other messages */
break
;
break
;
case
'C'
:
/* portal query command, no
tuple
s returned */
case
'C'
:
/* portal query command, no
row
s returned */
if
(
pqGets
(
cmdStatus
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
)
==
1
)
{
if
(
pqGets
(
cmdStatus
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"PQexec() -- query command completed, but return message from backend cannot be read"
);
"PQexec() -- query command completed, "
return
(
PGresult
*
)
NULL
;
"but return message from backend cannot be read."
);
return
(
PGresult
*
)
NULL
;
}
}
else
{
else
{
/*
/*
// since backend may produce more than one result for some commands
// since backend may produce more than one result for some commands
// need to poll until clear
// need to poll until clear
// send an empty query down, and keep reading out of the pipe
// send an empty query down, and keep reading out of the pipe
// until an 'I' is received.
// until an 'I' is received.
*/
*/
clear
=
0
;
clear
=
0
;
error
=
0
;
error
=
0
;
pqPuts
(
"Q "
,
pfout
,
pfdebug
);
/* send an empty query */
pqPuts
(
"Q "
,
pfout
,
pfdebug
);
/* send an empty query */
#ifdef PQ_NOTIFY_PATCH
#ifdef PQ_NOTIFY_PATCH
/*
/*
* Set a flag and process messages in the usual way because
* Set a flag and process messages in the usual way because
...
@@ -469,71 +469,71 @@ PQexec(PGconn* conn, const char* query)
...
@@ -469,71 +469,71 @@ PQexec(PGconn* conn, const char* query)
*/
*/
isCommand
=
1
;
isCommand
=
1
;
#else
#else
while
(
!
clear
)
while
(
!
clear
)
{
{
if
(
pqGets
(
buffer
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
if
(
pqGets
(
buffer
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
clear
=
1
;
clear
=
1
;
/*
/*
// Rules can create error messages while we are waiting
// Rules can create error messages while we are waiting
// for the 'I'.
// for the 'I'.
*/
*/
if
(
buffer
[
0
]
==
'E'
)
{
if
(
buffer
[
0
]
==
'E'
)
{
strcpy
(
conn
->
errorMessage
,
&
buffer
[
1
]);
strcpy
(
conn
->
errorMessage
,
&
buffer
[
1
]);
error
++
;
error
++
;
}
}
clear
=
(
buffer
[
0
]
==
'I'
);
clear
=
(
buffer
[
0
]
==
'I'
);
}
}
if
(
error
)
{
if
(
error
)
{
return
(
PGresult
*
)
NULL
;
return
(
PGresult
*
)
NULL
;
}
}
result
=
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
result
=
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
strncpy
(
result
->
cmdStatus
,
cmdStatus
,
CMDSTATUS_LEN
-
1
);
strncpy
(
result
->
cmdStatus
,
cmdStatus
,
CMDSTATUS_LEN
-
1
);
return
result
;
return
result
;
#endif
#endif
}
}
break
;
break
;
case
'E'
:
/* error return */
case
'E'
:
/* error return */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
(
void
)
sprintf
(
conn
->
errorMessage
,
(
void
)
sprintf
(
conn
->
errorMessage
,
"PQexec() -- error return detected from backend, but error message cannot be read"
);
"PQexec() -- error return detected from backend, "
"but attempt to read the error message failed."
);
}
}
return
(
PGresult
*
)
NULL
;
return
(
PGresult
*
)
NULL
;
break
;
break
;
case
'I'
:
/* empty query */
case
'I'
:
/* empty query */
/* read the throw away the closing '\0' */
/* read the throw away the closing '\0' */
{
{
int
c
;
int
c
;
if
((
c
=
pqGetc
(
pfin
,
pfdebug
))
!=
'\0'
)
{
if
((
c
=
pqGetc
(
pfin
,
pfdebug
))
!=
'\0'
)
{
fprintf
(
stderr
,
"error!, unexpected character %c following 'I'
\n
"
,
c
);
fprintf
(
stderr
,
"error!, unexpected character %c following 'I'
\n
"
,
c
);
}
}
#ifdef PQ_NOTIFY_PATCH
if
(
isCommand
)
{
if
(
isCommand
)
{
/*
/*
* If this is the result of a portal query command set the
* If this is the result of a portal query command set the
* command status and message accordingly. DZ - 31-8-1996
* command status and message accordingly. DZ - 31-8-1996
*/
*/
result
=
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
result
=
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
strncpy
(
result
->
cmdStatus
,
cmdStatus
,
CMDSTATUS_LEN
-
1
);
strncpy
(
result
->
cmdStatus
,
cmdStatus
,
CMDSTATUS_LEN
-
1
);
return
result
;
return
result
;
}
}
result
=
makeEmptyPGresult
(
conn
,
PGRES_EMPTY_QUERY
);
#endif
return
result
;
result
=
makeEmptyPGresult
(
conn
,
PGRES_EMPTY_QUERY
);
return
result
;
}
}
break
;
break
;
case
'N'
:
/* notices from the backend */
case
'N'
:
/* notices from the backend */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"PQexec() -- error return detected from backend, but error message cannot be read"
);
"PQexec() -- Notice detected from backend, "
return
(
PGresult
*
)
NULL
;
"but attempt to read the notice failed."
);
return
(
PGresult
*
)
NULL
;
}
}
else
else
fprintf
(
stderr
,
"%s"
,
conn
->
errorMessage
);
fprintf
(
stderr
,
"%s"
,
conn
->
errorMessage
);
break
;
break
;
case
'P'
:
/* synchronous (normal) portal */
case
'P'
:
/* synchronous (normal) portal */
pqGets
(
pname
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
);
/* read in
the
portal name*/
pqGets
(
pname
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
);
/* read in portal name*/
break
;
break
;
case
'T'
:
/* actual
tuple
results: */
case
'T'
:
/* actual
row
results: */
return
makePGresult
(
conn
,
pname
);
return
makePGresult
(
conn
,
pname
);
break
;
break
;
case
'D'
:
/* copy command began successfully */
case
'D'
:
/* copy command began successfully */
...
@@ -544,8 +544,8 @@ PQexec(PGconn* conn, const char* query)
...
@@ -544,8 +544,8 @@ PQexec(PGconn* conn, const char* query)
break
;
break
;
default:
default:
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"unknown protocol character %c read from backend
\n
"
,
"unknown protocol character %c read from backend
\n
"
,
id
);
id
);
return
(
PGresult
*
)
NULL
;
return
(
PGresult
*
)
NULL
;
}
/* switch */
}
/* switch */
}
/* while (1)*/
}
/* while (1)*/
...
@@ -571,13 +571,13 @@ PQnotifies(PGconn *conn)
...
@@ -571,13 +571,13 @@ PQnotifies(PGconn *conn)
if
(
!
conn
)
return
NULL
;
if
(
!
conn
)
return
NULL
;
if
(
conn
->
status
!=
CONNECTION_OK
)
if
(
conn
->
status
!=
CONNECTION_OK
)
return
NULL
;
return
NULL
;
/* RemHead returns NULL if list is empy */
/* RemHead returns NULL if list is empy */
e
=
DLRemHead
(
conn
->
notifyList
);
e
=
DLRemHead
(
conn
->
notifyList
);
if
(
e
)
if
(
e
)
return
(
PGnotify
*
)
DLE_VAL
(
e
);
return
(
PGnotify
*
)
DLE_VAL
(
e
);
else
else
return
NULL
;
return
NULL
;
}
}
/*
/*
...
@@ -590,12 +590,12 @@ PQnotifies(PGconn *conn)
...
@@ -590,12 +590,12 @@ PQnotifies(PGconn *conn)
* the terminating \n (like gets(3)).
* the terminating \n (like gets(3)).
*
*
* RETURNS:
* RETURNS:
*
EOF if it is detected or invalid arguments are given
*
EOF if it is detected or invalid arguments are given
*
0 if EOL is reached (i.e., \n has been read)
*
0 if EOL is reached (i.e., \n has been read)
*
(this is required for backward-compatibility -- this
*
(this is required for backward-compatibility -- this
*
routine used to always return EOF or 0, assuming that
*
routine used to always return EOF or 0, assuming that
*
the line ended within maxlen bytes.)
*
the line ended within maxlen bytes.)
*
1 in other cases
*
1 in other cases
*/
*/
int
int
PQgetline
(
PGconn
*
conn
,
char
*
s
,
int
maxlen
)
PQgetline
(
PGconn
*
conn
,
char
*
s
,
int
maxlen
)
...
@@ -605,22 +605,22 @@ PQgetline(PGconn *conn, char *s, int maxlen)
...
@@ -605,22 +605,22 @@ PQgetline(PGconn *conn, char *s, int maxlen)
if
(
!
conn
)
return
EOF
;
if
(
!
conn
)
return
EOF
;
if
(
!
conn
->
Pfin
||
!
s
||
maxlen
<=
1
)
if
(
!
conn
->
Pfin
||
!
s
||
maxlen
<=
1
)
return
(
EOF
);
return
(
EOF
);
for
(;
maxlen
>
1
&&
for
(;
maxlen
>
1
&&
(
c
=
pqGetc
(
conn
->
Pfin
,
conn
->
Pfdebug
))
!=
'\n'
&&
(
c
=
pqGetc
(
conn
->
Pfin
,
conn
->
Pfdebug
))
!=
'\n'
&&
c
!=
EOF
;
c
!=
EOF
;
--
maxlen
)
{
--
maxlen
)
{
*
s
++
=
c
;
*
s
++
=
c
;
}
}
*
s
=
'\0'
;
*
s
=
'\0'
;
if
(
c
==
EOF
)
{
if
(
c
==
EOF
)
{
return
(
EOF
);
/* error -- reached EOF before \n */
return
(
EOF
);
/* error -- reached EOF before \n */
}
else
if
(
c
==
'\n'
)
{
}
else
if
(
c
==
'\n'
)
{
return
(
0
);
/* done with this line */
return
(
0
);
/* done with this line */
}
}
return
(
1
);
/* returning a full buffer */
return
(
1
);
/* returning a full buffer */
}
}
...
@@ -634,19 +634,19 @@ void
...
@@ -634,19 +634,19 @@ void
PQputline
(
PGconn
*
conn
,
const
char
*
s
)
PQputline
(
PGconn
*
conn
,
const
char
*
s
)
{
{
if
(
conn
&&
(
conn
->
Pfout
))
{
if
(
conn
&&
(
conn
->
Pfout
))
{
(
void
)
fputs
(
s
,
conn
->
Pfout
);
(
void
)
fputs
(
s
,
conn
->
Pfout
);
fflush
(
conn
->
Pfout
);
fflush
(
conn
->
Pfout
);
}
}
}
}
/*
/*
* PQendcopy
* PQendcopy
*
called while waiting for the backend to respond with success/failure
*
called while waiting for the backend to respond with success/failure
*
to a "copy".
*
to a "copy".
*
*
* RETURNS:
* RETURNS:
*
0 on failure
*
0 on failure
*
1 on success
*
1 on success
*/
*/
int
int
PQendcopy
(
PGconn
*
conn
)
PQendcopy
(
PGconn
*
conn
)
...
@@ -660,26 +660,27 @@ PQendcopy(PGconn *conn)
...
@@ -660,26 +660,27 @@ PQendcopy(PGconn *conn)
pfdebug
=
conn
->
Pfdebug
;
pfdebug
=
conn
->
Pfdebug
;
if
(
(
id
=
pqGetc
(
pfin
,
pfdebug
))
>
0
)
if
(
(
id
=
pqGetc
(
pfin
,
pfdebug
))
>
0
)
return
(
0
);
return
(
0
);
switch
(
id
)
{
switch
(
id
)
{
case
'Z'
:
/* backend finished the copy */
case
'Z'
:
/* backend finished the copy */
return
(
1
);
return
(
1
);
case
'E'
:
case
'E'
:
case
'N'
:
case
'N'
:
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"Error return detected from backend, but error message cannot be read"
);
"Error return detected from backend, "
}
"but attempt to read the message failed."
);
return
(
0
);
}
break
;
return
(
0
);
break
;
default:
default:
(
void
)
sprintf
(
conn
->
errorMessage
,
(
void
)
sprintf
(
conn
->
errorMessage
,
"FATAL: PQendcopy: protocol error: id=%x
\n
"
,
"FATAL: PQendcopy: protocol error: id=%x
\n
"
,
id
);
id
);
fputs
(
conn
->
errorMessage
,
stderr
);
fputs
(
conn
->
errorMessage
,
stderr
);
fprintf
(
stderr
,
"resetting connection
\n
"
);
fprintf
(
stderr
,
"resetting connection
\n
"
);
PQreset
(
conn
);
PQreset
(
conn
);
return
(
0
);
return
(
0
);
}
}
}
}
...
@@ -706,12 +707,12 @@ fill (int length, int max, char filler, FILE *fp)
...
@@ -706,12 +707,12 @@ fill (int length, int max, char filler, FILE *fp)
*/
*/
void
void
PQdisplayTuples
(
PGresult
*
res
,
PQdisplayTuples
(
PGresult
*
res
,
FILE
*
fp
,
/* where to send the output */
FILE
*
fp
,
/* where to send the output */
int
fillAlign
,
/* pad the fields with spaces */
int
fillAlign
,
/* pad the fields with spaces */
const
char
*
fieldSep
,
/* field separator */
const
char
*
fieldSep
,
/* field separator */
int
printHeader
,
/* display headers? */
int
printHeader
,
/* display headers? */
int
quiet
int
quiet
)
)
{
{
#define DEFAULT_FIELD_SEP " "
#define DEFAULT_FIELD_SEP " "
...
@@ -721,14 +722,14 @@ PQdisplayTuples(PGresult *res,
...
@@ -721,14 +722,14 @@ PQdisplayTuples(PGresult *res,
int
fLength
[
MAX_FIELDS
];
int
fLength
[
MAX_FIELDS
];
if
(
fieldSep
==
NULL
)
if
(
fieldSep
==
NULL
)
fieldSep
=
DEFAULT_FIELD_SEP
;
fieldSep
=
DEFAULT_FIELD_SEP
;
/* Get some useful info about the results */
/* Get some useful info about the results */
nFields
=
PQnfields
(
res
);
nFields
=
PQnfields
(
res
);
nTuples
=
PQntuples
(
res
);
nTuples
=
PQntuples
(
res
);
if
(
fp
==
NULL
)
if
(
fp
==
NULL
)
fp
=
stdout
;
fp
=
stdout
;
/* Zero the initial field lengths */
/* Zero the initial field lengths */
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
...
@@ -737,47 +738,47 @@ PQdisplayTuples(PGresult *res,
...
@@ -737,47 +738,47 @@ PQdisplayTuples(PGresult *res,
/* Find the max length of each field in the result */
/* Find the max length of each field in the result */
/* will be somewhat time consuming for very large results */
/* will be somewhat time consuming for very large results */
if
(
fillAlign
)
{
if
(
fillAlign
)
{
for
(
i
=
0
;
i
<
nTuples
;
i
++
)
{
for
(
i
=
0
;
i
<
nTuples
;
i
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
if
(
PQgetlength
(
res
,
i
,
j
)
>
fLength
[
j
])
if
(
PQgetlength
(
res
,
i
,
j
)
>
fLength
[
j
])
fLength
[
j
]
=
PQgetlength
(
res
,
i
,
j
);
fLength
[
j
]
=
PQgetlength
(
res
,
i
,
j
);
}
}
}
}
}
}
if
(
printHeader
)
{
if
(
printHeader
)
{
/* first, print out the attribute names */
/* first, print out the attribute names */
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
fputs
(
PQfname
(
res
,
i
),
fp
);
fputs
(
PQfname
(
res
,
i
),
fp
);
if
(
fillAlign
)
if
(
fillAlign
)
fill
(
strlen
(
PQfname
(
res
,
i
)),
fLength
[
i
],
' '
,
fp
);
fill
(
strlen
(
PQfname
(
res
,
i
)),
fLength
[
i
],
' '
,
fp
);
fputs
(
fieldSep
,
fp
);
fputs
(
fieldSep
,
fp
);
}
}
fprintf
(
fp
,
"
\n
"
);
fprintf
(
fp
,
"
\n
"
);
/* Underline the attribute names */
/* Underline the attribute names */
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
if
(
fillAlign
)
if
(
fillAlign
)
fill
(
0
,
fLength
[
i
],
'-'
,
fp
);
fill
(
0
,
fLength
[
i
],
'-'
,
fp
);
fputs
(
fieldSep
,
fp
);
fputs
(
fieldSep
,
fp
);
}
}
fprintf
(
fp
,
"
\n
"
);
fprintf
(
fp
,
"
\n
"
);
}
}
/* next, print out the instances */
/* next, print out the instances */
for
(
i
=
0
;
i
<
nTuples
;
i
++
)
{
for
(
i
=
0
;
i
<
nTuples
;
i
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
fprintf
(
fp
,
"%s"
,
PQgetvalue
(
res
,
i
,
j
));
fprintf
(
fp
,
"%s"
,
PQgetvalue
(
res
,
i
,
j
));
if
(
fillAlign
)
if
(
fillAlign
)
fill
(
strlen
(
PQgetvalue
(
res
,
i
,
j
)),
fLength
[
j
],
' '
,
fp
);
fill
(
strlen
(
PQgetvalue
(
res
,
i
,
j
)),
fLength
[
j
],
' '
,
fp
);
fputs
(
fieldSep
,
fp
);
fputs
(
fieldSep
,
fp
);
}
}
fprintf
(
fp
,
"
\n
"
);
fprintf
(
fp
,
"
\n
"
);
}
}
if
(
!
quiet
)
if
(
!
quiet
)
fprintf
(
fp
,
"
\n
Query returned %d row%s.
\n
"
,
PQntuples
(
res
),
fprintf
(
fp
,
"
\n
Query returned %d row%s.
\n
"
,
PQntuples
(
res
),
(
PQntuples
(
res
)
==
1
)
?
""
:
"s"
);
(
PQntuples
(
res
)
==
1
)
?
""
:
"s"
);
fflush
(
fp
);
fflush
(
fp
);
}
}
...
@@ -792,11 +793,11 @@ PQdisplayTuples(PGresult *res,
...
@@ -792,11 +793,11 @@ PQdisplayTuples(PGresult *res,
*/
*/
void
void
PQprintTuples
(
PGresult
*
res
,
PQprintTuples
(
PGresult
*
res
,
FILE
*
fout
,
/* output stream */
FILE
*
fout
,
/* output stream */
int
PrintAttNames
,
/* print attribute names or not*/
int
PrintAttNames
,
/* print attribute names or not*/
int
TerseOutput
,
/* delimiter bars or not?*/
int
TerseOutput
,
/* delimiter bars or not?*/
int
colWidth
/* width of column, if 0, use variable width */
int
colWidth
/* width of column, if 0, use variable width */
)
)
{
{
int
nFields
;
int
nFields
;
int
nTups
;
int
nTups
;
...
@@ -813,426 +814,464 @@ PQprintTuples(PGresult *res,
...
@@ -813,426 +814,464 @@ PQprintTuples(PGresult *res,
}
else
}
else
sprintf
(
formatString
,
"%%s %%s"
);
sprintf
(
formatString
,
"%%s %%s"
);
if
(
nFields
>
0
)
{
/* only print tuples with at least 1 field. */
if
(
nFields
>
0
)
{
/* only print rows with at least 1 field. */
if
(
!
TerseOutput
)
if
(
!
TerseOutput
)
{
{
int
width
;
int
width
;
width
=
nFields
*
14
;
width
=
nFields
*
14
;
tborder
=
malloc
(
width
+
1
);
tborder
=
malloc
(
width
+
1
);
for
(
i
=
0
;
i
<=
width
;
i
++
)
for
(
i
=
0
;
i
<=
width
;
i
++
)
tborder
[
i
]
=
'-'
;
tborder
[
i
]
=
'-'
;
tborder
[
i
]
=
'\0'
;
tborder
[
i
]
=
'\0'
;
fprintf
(
fout
,
"%s
\n
"
,
tborder
);
fprintf
(
fout
,
"%s
\n
"
,
tborder
);
}
}
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
if
(
PrintAttNames
)
{
if
(
PrintAttNames
)
{
fprintf
(
fout
,
formatString
,
fprintf
(
fout
,
formatString
,
TerseOutput
?
""
:
"|"
,
TerseOutput
?
""
:
"|"
,
PQfname
(
res
,
i
));
PQfname
(
res
,
i
));
}
}
}
}
if
(
PrintAttNames
)
{
if
(
PrintAttNames
)
{
if
(
TerseOutput
)
if
(
TerseOutput
)
fprintf
(
fout
,
"
\n
"
);
fprintf
(
fout
,
"
\n
"
);
else
else
fprintf
(
fout
,
"|
\n
%s
\n
"
,
tborder
);
fprintf
(
fout
,
"|
\n
%s
\n
"
,
tborder
);
}
}
for
(
i
=
0
;
i
<
nTups
;
i
++
)
{
for
(
i
=
0
;
i
<
nTups
;
i
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
char
*
pval
=
PQgetvalue
(
res
,
i
,
j
);
char
*
pval
=
PQgetvalue
(
res
,
i
,
j
);
fprintf
(
fout
,
formatString
,
fprintf
(
fout
,
formatString
,
TerseOutput
?
""
:
"|"
,
TerseOutput
?
""
:
"|"
,
pval
?
pval
:
""
);
pval
?
pval
:
""
);
}
}
if
(
TerseOutput
)
if
(
TerseOutput
)
fprintf
(
fout
,
"
\n
"
);
fprintf
(
fout
,
"
\n
"
);
else
else
fprintf
(
fout
,
"|
\n
%s
\n
"
,
tborder
);
fprintf
(
fout
,
"|
\n
%s
\n
"
,
tborder
);
}
}
}
}
static
void
do_field
(
PQprintOpt
*
po
,
PGresult
*
res
,
const
int
i
,
const
int
j
,
char
*
buf
,
const
int
fs_len
,
char
*
fields
[],
const
int
nFields
,
char
*
fieldNames
[],
unsigned
char
fieldNotNum
[],
int
fieldMax
[],
const
int
fieldMaxLen
,
FILE
*
fout
)
{
char
*
pval
,
*
p
,
*
o
;
int
plen
;
bool
skipit
;
plen
=
PQgetlength
(
res
,
i
,
j
);
pval
=
PQgetvalue
(
res
,
i
,
j
);
if
(
plen
<
1
||
!
pval
||
!*
pval
)
{
if
(
po
->
align
||
po
->
expanded
)
skipit
=
true
;
else
{
skipit
=
false
;
goto
efield
;
}
}
else
skipit
=
false
;
if
(
!
skipit
)
{
for
(
p
=
pval
,
o
=
buf
;
*
p
;
*
(
o
++
)
=*
(
p
++
))
{
if
((
fs_len
==
1
&&
(
*
p
==*
(
po
->
fieldSep
)))
||
*
p
==
'\\'
)
*
(
o
++
)
=
'\\'
;
if
(
po
->
align
&&
(
*
pval
==
'E'
||
*
pval
==
'e'
||
!
((
*
p
>=
'0'
&&
*
p
<=
'9'
)
||
*
p
==
'.'
||
*
p
==
'E'
||
*
p
==
'e'
||
*
p
==
' '
||
*
p
==
'-'
)))
fieldNotNum
[
j
]
=
1
;
}
*
o
=
'\0'
;
if
(
!
po
->
expanded
&&
(
po
->
align
||
po
->
html3
))
{
int
n
=
strlen
(
buf
);
if
(
n
>
fieldMax
[
j
])
fieldMax
[
j
]
=
n
;
if
(
!
(
fields
[
i
*
nFields
+
j
]
=
(
char
*
)
malloc
(
n
+
1
)))
{
perror
(
"malloc"
);
exit
(
1
);
}
strcpy
(
fields
[
i
*
nFields
+
j
],
buf
);
}
else
{
if
(
po
->
expanded
)
{
if
(
po
->
html3
)
fprintf
(
fout
,
"<tr><td align=left><b>%s</b></td>"
"<td align=%s>%s</td></tr>
\n
"
,
fieldNames
[
j
],
fieldNotNum
[
j
]
?
"left"
:
"right"
,
buf
);
else
{
if
(
po
->
align
)
fprintf
(
fout
,
"%-*s%s %s
\n
"
,
fieldMaxLen
-
fs_len
,
fieldNames
[
j
],
po
->
fieldSep
,
buf
);
else
fprintf
(
fout
,
"%s%s%s
\n
"
,
fieldNames
[
j
],
po
->
fieldSep
,
buf
);
}
}
else
{
if
(
!
po
->
html3
)
{
fputs
(
buf
,
fout
);
efield:
if
((
j
+
1
)
<
nFields
)
fputs
(
po
->
fieldSep
,
fout
);
else
fputc
(
'\n'
,
fout
);
}
}
}
}
}
}
}
static
void
do_header
(
FILE
*
fout
,
PQprintOpt
*
po
,
const
int
nFields
,
int
fieldMax
[],
char
*
fieldNames
[],
unsigned
char
fieldNotNum
[],
const
int
fs_len
,
char
*
border
,
PGresult
*
res
)
{
int
j
;
/* for loop index */
if
(
po
->
html3
)
fputs
(
"<tr>"
,
fout
);
else
{
int
j
;
/* for loop index */
int
tot
=
0
;
int
n
=
0
;
char
*
p
;
for
(;
n
<
nFields
;
n
++
)
tot
+=
fieldMax
[
n
]
+
fs_len
+
(
po
->
standard
?
2
:
0
);
if
(
po
->
standard
)
tot
+=
fs_len
*
2
+
2
;
if
(
!
(
p
=
border
=
malloc
(
tot
+
1
)))
{
perror
(
"malloc"
);
exit
(
1
);
}
if
(
po
->
standard
)
{
char
*
fs
=
po
->
fieldSep
;
while
(
*
fs
++
)
*
p
++=
'+'
;
}
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
int
len
;
for
(
len
=
fieldMax
[
j
]
+
(
po
->
standard
?
2
:
0
)
;
len
--
;
*
p
++=
'-'
);
if
(
po
->
standard
||
(
j
+
1
)
<
nFields
)
{
char
*
fs
=
po
->
fieldSep
;
while
(
*
fs
++
)
*
p
++=
'+'
;
}
}
*
p
=
'\0'
;
if
(
po
->
standard
)
fprintf
(
fout
,
"%s
\n
"
,
border
);
}
if
(
po
->
standard
)
fputs
(
po
->
fieldSep
,
fout
);
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
char
*
s
=
PQfname
(
res
,
j
);
if
(
po
->
html3
)
{
fprintf
(
fout
,
"<th align=%s>%s</th>"
,
fieldNotNum
[
j
]
?
"left"
:
"right"
,
fieldNames
[
j
]);
}
else
{
int
n
=
strlen
(
s
);
if
(
n
>
fieldMax
[
j
])
fieldMax
[
j
]
=
n
;
if
(
po
->
standard
)
fprintf
(
fout
,
fieldNotNum
[
j
]
?
" %-*s "
:
" %*s "
,
fieldMax
[
j
],
s
);
else
fprintf
(
fout
,
fieldNotNum
[
j
]
?
"%-*s"
:
"%*s"
,
fieldMax
[
j
],
s
);
if
(
po
->
standard
||
(
j
+
1
)
<
nFields
)
fputs
(
po
->
fieldSep
,
fout
);
}
}
if
(
po
->
html3
)
fputs
(
"</tr>
\n
"
,
fout
);
else
fprintf
(
fout
,
"
\n
%s
\n
"
,
border
);
}
static
void
output_row
(
FILE
*
fout
,
PQprintOpt
*
po
,
const
int
nFields
,
char
*
fields
[],
unsigned
char
fieldNotNum
[],
int
fieldMax
[],
char
*
border
,
const
int
row_index
)
{
int
field_index
;
/* for loop index */
if
(
po
->
html3
)
fputs
(
"<tr>"
,
fout
);
else
if
(
po
->
standard
)
fputs
(
po
->
fieldSep
,
fout
);
for
(
field_index
=
0
;
field_index
<
nFields
;
field_index
++
)
{
char
*
p
=
fields
[
row_index
*
nFields
+
field_index
];
if
(
po
->
html3
)
fprintf
(
fout
,
"<td align=%s>%s</td>"
,
fieldNotNum
[
field_index
]
?
"left"
:
"right"
,
p
?
p
:
""
);
else
{
fprintf
(
fout
,
fieldNotNum
[
field_index
]
?
(
po
->
standard
?
" %-*s "
:
"%-*s"
)
:
(
po
->
standard
?
" %*s "
:
"%*s"
),
fieldMax
[
field_index
],
p
?
p
:
""
);
if
(
po
->
standard
||
field_index
+
1
<
nFields
)
fputs
(
po
->
fieldSep
,
fout
);
}
if
(
p
)
free
(
p
);
}
if
(
po
->
html3
)
fputs
(
"</tr>"
,
fout
);
else
if
(
po
->
standard
)
fprintf
(
fout
,
"
\n
%s"
,
border
);
fputc
(
'\n'
,
fout
);
}
/*
/*
* PQprint()
* PQprint()
*
*
* new PQprintTuples routine (proff@suburbia.net)
* Format results of a query for printing.
*
* PQprintOpt is a typedef (structure) that containes
* PQprintOpt is a typedef (structure) that containes
* various flags and options. consult libpq-fe.h for
* various flags and options. consult libpq-fe.h for
* details
* details
*
* Obsoletes PQprintTuples.
*/
*/
void
void
PQprint
(
FILE
*
fout
,
PQprint
(
FILE
*
fout
,
PGresult
*
res
,
PGresult
*
res
,
PQprintOpt
*
po
PQprintOpt
*
po
)
)
{
{
int
nFields
;
int
nFields
;
nFields
=
PQnfields
(
res
);
nFields
=
PQnfields
(
res
);
if
(
nFields
>
0
)
{
/* only print tuples with at least 1 field. */
if
(
nFields
>
0
)
{
/* only print rows with at least 1 field. */
int
i
,
j
;
int
i
,
j
;
int
nTups
;
int
nTups
;
int
*
fieldMax
=
NULL
;
/* in case we don't use them */
int
*
fieldMax
=
NULL
;
/* in case we don't use them */
unsigned
char
*
fieldNotNum
=
NULL
;
unsigned
char
*
fieldNotNum
=
NULL
;
char
*
border
=
NULL
;
char
*
border
=
NULL
;
char
**
fields
=
NULL
;
char
**
fields
=
NULL
;
char
**
fieldNames
;
char
**
fieldNames
;
int
fieldMaxLen
=
0
;
int
fieldMaxLen
=
0
;
int
numFieldName
;
int
numFieldName
;
int
fs_len
=
strlen
(
po
->
fieldSep
);
int
fs_len
=
strlen
(
po
->
fieldSep
);
int
total_line_length
=
0
;
int
total_line_length
=
0
;
int
usePipe
=
0
;
int
usePipe
=
0
;
char
*
pagerenv
;
char
*
pagerenv
;
char
buf
[
8192
*
2
+
1
];
char
buf
[
8192
*
2
+
1
];
nTups
=
PQntuples
(
res
);
nTups
=
PQntuples
(
res
);
if
(
!
(
fieldNames
=
(
char
**
)
calloc
(
nFields
,
sizeof
(
char
*
))))
if
(
!
(
fieldNames
=
(
char
**
)
calloc
(
nFields
,
sizeof
(
char
*
))))
{
{
perror
(
"calloc"
);
perror
(
"calloc"
);
exit
(
1
);
exit
(
1
);
}
}
if
(
!
(
fieldNotNum
=
(
unsigned
char
*
)
calloc
(
nFields
,
1
)))
{
if
(
!
(
fieldNotNum
=
(
unsigned
char
*
)
calloc
(
nFields
,
1
)))
perror
(
"calloc"
);
{
exit
(
1
);
perror
(
"calloc"
);
}
exit
(
1
);
if
(
!
(
fieldMax
=
(
int
*
)
calloc
(
nFields
,
sizeof
(
int
))))
{
}
perror
(
"calloc"
);
if
(
!
(
fieldMax
=
(
int
*
)
calloc
(
nFields
,
sizeof
(
int
))))
exit
(
1
);
{
}
perror
(
"calloc"
);
for
(
numFieldName
=
0
;
exit
(
1
);
po
->
fieldName
&&
po
->
fieldName
[
numFieldName
];
}
numFieldName
++
)
for
(
numFieldName
=
0
;
po
->
fieldName
&&
po
->
fieldName
[
numFieldName
];
numFieldName
++
)
;
;
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
int
len
;
{
char
*
s
=
int
len
;
(
j
<
numFieldName
&&
po
->
fieldName
[
j
][
0
])
?
char
*
s
=
(
j
<
numFieldName
&&
po
->
fieldName
[
j
][
0
])
?
po
->
fieldName
[
j
]
:
PQfname
(
res
,
j
);
po
->
fieldName
[
j
]
:
PQfname
(
res
,
j
);
fieldNames
[
j
]
=
s
;
fieldNames
[
j
]
=
s
;
len
=
s
?
strlen
(
s
)
:
0
;
len
=
s
?
strlen
(
s
)
:
0
;
fieldMax
[
j
]
=
len
;
fieldMax
[
j
]
=
len
;
/*
len
+=
fs_len
;
if (po->header && len<5)
if
(
len
>
fieldMaxLen
)
len=5;
fieldMaxLen
=
len
;
*/
total_line_length
+=
len
;
len
+=
fs_len
;
}
if
(
len
>
fieldMaxLen
)
fieldMaxLen
=
len
;
total_line_length
+=
len
;
}
total_line_length
+=
nFields
*
strlen
(
po
->
fieldSep
)
+
1
;
total_line_length
+=
nFields
*
strlen
(
po
->
fieldSep
)
+
1
;
if
(
fout
==
NULL
)
if
(
fout
==
NULL
)
fout
=
stdout
;
fout
=
stdout
;
if
(
po
->
pager
&&
fout
==
stdout
&&
if
(
po
->
pager
&&
fout
==
stdout
&&
isatty
(
fileno
(
stdin
))
&&
isatty
(
fileno
(
stdin
))
&&
isatty
(
fileno
(
stdout
)))
isatty
(
fileno
(
stdout
)))
{
{
/* try to pipe to the pager program if possible */
/* try to pipe to the pager program if possible */
#ifdef TIOCGWINSZ
#ifdef TIOCGWINSZ
if
(
ioctl
(
fileno
(
stdout
),
TIOCGWINSZ
,
&
screen_size
)
==
-
1
||
if
(
ioctl
(
fileno
(
stdout
),
TIOCGWINSZ
,
&
screen_size
)
==
-
1
||
screen_size
.
ws_col
==
0
||
screen_size
.
ws_col
==
0
||
screen_size
.
ws_row
==
0
)
screen_size
.
ws_row
==
0
)
{
{
#endif
#endif
screen_size
.
ws_row
=
24
;
screen_size
.
ws_row
=
24
;
screen_size
.
ws_col
=
80
;
screen_size
.
ws_col
=
80
;
#ifdef TIOCGWINSZ
#ifdef TIOCGWINSZ
}
}
#endif
#endif
pagerenv
=
getenv
(
"PAGER"
);
pagerenv
=
getenv
(
"PAGER"
);
if
(
pagerenv
!=
NULL
&&
if
(
pagerenv
!=
NULL
&&
pagerenv
[
0
]
!=
'\0'
&&
pagerenv
[
0
]
!=
'\0'
&&
!
po
->
html3
&&
!
po
->
html3
&&
((
po
->
expanded
&&
((
po
->
expanded
&&
nTups
*
(
nFields
+
1
)
>=
screen_size
.
ws_row
)
||
nTups
*
(
nFields
+
1
)
>=
screen_size
.
ws_row
)
||
(
!
po
->
expanded
&&
(
!
po
->
expanded
&&
nTups
*
(
total_line_length
/
screen_size
.
ws_col
+
1
)
*
nTups
*
(
total_line_length
/
screen_size
.
ws_col
+
1
)
*
(
1
+
(
po
->
standard
!=
0
))
>=
(
1
+
(
po
->
standard
!=
0
))
>=
screen_size
.
ws_row
-
screen_size
.
ws_row
-
(
po
->
header
!=
0
)
*
(
po
->
header
!=
0
)
*
(
total_line_length
/
screen_size
.
ws_col
+
1
)
*
2
(
total_line_length
/
screen_size
.
ws_col
+
1
)
*
2
-
(
po
->
header
!=
0
)
*
2
/* row count and newline */
-
(
po
->
header
!=
0
)
*
2
/* row count and newline */
)))
)))
{
{
fout
=
popen
(
pagerenv
,
"w"
);
fout
=
popen
(
pagerenv
,
"w"
);
if
(
fout
)
{
if
(
fout
)
{
usePipe
=
1
;
usePipe
=
1
;
signal
(
SIGPIPE
,
SIG_IGN
);
signal
(
SIGPIPE
,
SIG_IGN
);
}
else
}
else
fout
=
stdout
;
fout
=
stdout
;
}
}
}
}
if
(
!
po
->
expanded
&&
(
po
->
align
||
po
->
html3
))
{
if
(
!
po
->
expanded
&&
(
po
->
align
||
po
->
html3
))
if
(
!
(
fields
=
(
char
**
)
calloc
(
nFields
*
(
nTups
+
1
),
sizeof
(
char
*
))))
{
{
perror
(
"calloc"
);
if
(
!
(
fields
=
(
char
**
)
calloc
(
nFields
*
(
nTups
+
1
),
sizeof
(
char
*
))))
exit
(
1
);
{
}
perror
(
"calloc"
);
}
else
exit
(
1
);
if
(
po
->
header
&&
!
po
->
html3
)
{
}
if
(
po
->
expanded
)
{
}
if
(
po
->
align
)
else
fprintf
(
fout
,
"%-*s%s Value
\n
"
,
if
(
po
->
header
&&
!
po
->
html3
)
fieldMaxLen
-
fs_len
,
"Field"
,
po
->
fieldSep
);
{
else
if
(
po
->
expanded
)
fprintf
(
fout
,
"%s%sValue
\n
"
,
"Field"
,
po
->
fieldSep
);
{
}
else
{
if
(
po
->
align
)
int
len
=
0
;
fprintf
(
fout
,
"%-*s%s Value
\n
"
,
fieldMaxLen
-
fs_len
,
"Field"
,
po
->
fieldSep
);
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
else
char
*
s
=
fieldNames
[
j
];
fprintf
(
fout
,
"%s%sValue
\n
"
,
"Field"
,
po
->
fieldSep
);
fputs
(
s
,
fout
);
}
len
+=
strlen
(
s
)
+
fs_len
;
else
if
((
j
+
1
)
<
nFields
)
{
fputs
(
po
->
fieldSep
,
fout
);
int
len
=
0
;
}
for
(
j
=
0
;
j
<
nFields
;
j
++
)
fputc
(
'\n'
,
fout
);
{
for
(
len
-=
fs_len
;
len
--
;
fputc
(
'-'
,
fout
));
char
*
s
=
fieldNames
[
j
];
fputc
(
'\n'
,
fout
);
fputs
(
s
,
fout
);
}
len
+=
strlen
(
s
)
+
fs_len
;
}
if
((
j
+
1
)
<
nFields
)
if
(
po
->
expanded
&&
po
->
html3
)
{
fputs
(
po
->
fieldSep
,
fout
);
if
(
po
->
caption
)
}
fprintf
(
fout
,
"<centre><h2>%s</h2></centre>
\n
"
,
po
->
caption
);
fputc
(
'\n'
,
fout
);
else
for
(
len
-=
fs_len
;
len
--
;
fputc
(
'-'
,
fout
));
fprintf
(
fout
,
fputc
(
'\n'
,
fout
);
"<centre><h2>"
}
"Query retrieved %d rows * %d fields"
}
"</h2></centre>
\n
"
,
if
(
po
->
expanded
&&
po
->
html3
)
nTups
,
nFields
);
{
}
if
(
po
->
caption
)
for
(
i
=
0
;
i
<
nTups
;
i
++
)
{
fprintf
(
fout
,
"<centre><h2>%s</h2></centre>
\n
"
,
po
->
caption
);
if
(
po
->
expanded
)
{
else
if
(
po
->
html3
)
fprintf
(
fout
,
"<centre><h2>Query retrieved %d tuples * %d fields</h2></centre>
\n
"
,
nTups
,
nFields
);
fprintf
(
fout
,
}
"<table %s><caption align=high>%d</caption>
\n
"
,
for
(
i
=
0
;
i
<
nTups
;
i
++
)
po
->
tableOpt
?
po
->
tableOpt
:
""
,
i
);
{
else
if
(
po
->
expanded
)
fprintf
(
fout
,
"-- RECORD %d --
\n
"
,
i
);
{
}
if
(
po
->
html3
)
fprintf
(
fout
,
"<table %s><caption align=high>%d</caption>
\n
"
,
po
->
tableOpt
?
po
->
tableOpt
:
""
,
i
);
else
fprintf
(
fout
,
"-- RECORD %d --
\n
"
,
i
);
}
for
(
j
=
0
;
j
<
nFields
;
j
++
)
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
do_field
(
po
,
res
,
i
,
j
,
buf
,
fs_len
,
fields
,
nFields
,
char
*
pval
,
*
p
,
*
o
;
fieldNames
,
fieldNotNum
,
int
plen
;
fieldMax
,
fieldMaxLen
,
fout
);
if
((
plen
=
PQgetlength
(
res
,
i
,
j
))
<
1
||
!
(
pval
=
PQgetvalue
(
res
,
i
,
j
))
||
!*
pval
)
if
(
po
->
html3
&&
po
->
expanded
)
{
fputs
(
"</table>
\n
"
,
fout
);
if
(
po
->
align
||
po
->
expanded
)
}
continue
;
if
(
!
po
->
expanded
&&
(
po
->
align
||
po
->
html3
))
{
goto
efield
;
if
(
po
->
html3
)
{
}
if
(
po
->
header
)
{
for
(
p
=
pval
,
o
=
buf
;
*
p
;
*
(
o
++
)
=*
(
p
++
))
if
(
po
->
caption
)
{
fprintf
(
fout
,
if
((
fs_len
==
1
&&
(
*
p
==*
(
po
->
fieldSep
)))
||
*
p
==
'\\'
)
"<table %s><caption align=high>%s</caption>
\n
"
,
*
(
o
++
)
=
'\\'
;
po
->
tableOpt
?
po
->
tableOpt
:
""
,
if
(
po
->
align
&&
(
*
pval
==
'E'
||
*
pval
==
'e'
||
po
->
caption
);
!
((
*
p
>=
'0'
&&
*
p
<=
'9'
)
||
*
p
==
'.'
||
*
p
==
'E'
||
*
p
==
'e'
||
*
p
==
' '
||
*
p
==
'-'
)))
else
fieldNotNum
[
j
]
=
1
;
fprintf
(
fout
,
}
"<table %s><caption align=high>"
*
o
=
'\0'
;
"Retrieved %d rows * %d fields"
if
(
!
po
->
expanded
&&
(
po
->
align
||
po
->
html3
))
"</caption>
\n
"
,
{
po
->
tableOpt
?
po
->
tableOpt
:
""
,
nTups
,
nFields
);
int
n
=
strlen
(
buf
);
}
else
if
(
n
>
fieldMax
[
j
])
fprintf
(
fout
,
"<table %s>"
,
po
->
tableOpt
?
po
->
tableOpt
:
""
);
fieldMax
[
j
]
=
n
;
}
if
(
!
(
fields
[
i
*
nFields
+
j
]
=
(
char
*
)
malloc
(
n
+
1
)))
if
(
po
->
header
)
{
do_header
(
fout
,
po
,
nFields
,
fieldMax
,
fieldNames
,
fieldNotNum
,
perror
(
"malloc"
);
fs_len
,
border
,
res
);
exit
(
1
);
for
(
i
=
0
;
i
<
nTups
;
i
++
)
}
output_row
(
fout
,
po
,
nFields
,
fields
,
strcpy
(
fields
[
i
*
nFields
+
j
],
buf
);
fieldNotNum
,
fieldMax
,
border
,
i
);
}
free
(
fields
);
else
}
{
if
(
po
->
header
&&
!
po
->
html3
)
if
(
po
->
expanded
)
fprintf
(
fout
,
"(%d row%s)
\n\n
"
,
PQntuples
(
res
),
{
(
PQntuples
(
res
)
==
1
)
?
""
:
"s"
);
if
(
po
->
html3
)
free
(
fieldMax
);
fprintf
(
fout
,
"<tr><td align=left><b>%s</b></td><td align=%s>%s</td></tr>
\n
"
,
free
(
fieldNotNum
);
fieldNames
[
j
],
fieldNotNum
[
j
]
?
"left"
:
"right"
,
buf
);
free
(
fieldNames
);
else
if
(
usePipe
)
{
{
pclose
(
fout
);
if
(
po
->
align
)
signal
(
SIGPIPE
,
SIG_DFL
);
fprintf
(
fout
,
"%-*s%s %s
\n
"
,
fieldMaxLen
-
fs_len
,
fieldNames
[
j
],
po
->
fieldSep
,
buf
);
}
else
if
(
border
)
fprintf
(
fout
,
"%s%s%s
\n
"
,
fieldNames
[
j
],
po
->
fieldSep
,
buf
);
free
(
border
);
}
if
(
po
->
html3
&&
!
po
->
expanded
)
}
fputs
(
"</table>
\n
"
,
fout
);
else
}
{
if
(
!
po
->
html3
)
{
fputs
(
buf
,
fout
);
efield:
if
((
j
+
1
)
<
nFields
)
fputs
(
po
->
fieldSep
,
fout
);
else
fputc
(
'\n'
,
fout
);
}
}
}
}
if
(
po
->
html3
&&
po
->
expanded
)
fputs
(
"</table>
\n
"
,
fout
);
}
if
(
!
po
->
expanded
&&
(
po
->
align
||
po
->
html3
))
{
if
(
po
->
html3
)
{
if
(
po
->
header
)
{
if
(
po
->
caption
)
fprintf
(
fout
,
"<table %s><caption align=high>%s</caption>
\n
"
,
po
->
tableOpt
?
po
->
tableOpt
:
""
,
po
->
caption
);
else
fprintf
(
fout
,
"<table %s><caption align=high>Retrieved %d tuples * %d fields</caption>
\n
"
,
po
->
tableOpt
?
po
->
tableOpt
:
""
,
nTups
,
nFields
);
}
else
fprintf
(
fout
,
"<table %s>"
,
po
->
tableOpt
?
po
->
tableOpt
:
""
);
}
if
(
po
->
header
)
{
if
(
po
->
html3
)
fputs
(
"<tr>"
,
fout
);
else
{
int
tot
=
0
;
int
n
=
0
;
char
*
p
;
for
(;
n
<
nFields
;
n
++
)
tot
+=
fieldMax
[
n
]
+
fs_len
+
(
po
->
standard
?
2
:
0
);
if
(
po
->
standard
)
tot
+=
fs_len
*
2
+
2
;
if
(
!
(
p
=
border
=
malloc
(
tot
+
1
)))
{
perror
(
"malloc"
);
exit
(
1
);
}
if
(
po
->
standard
)
{
char
*
fs
=
po
->
fieldSep
;
while
(
*
fs
++
)
*
p
++=
'+'
;
}
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
int
len
;
for
(
len
=
fieldMax
[
j
]
+
(
po
->
standard
?
2
:
0
)
;
len
--
;
*
p
++=
'-'
);
if
(
po
->
standard
||
(
j
+
1
)
<
nFields
)
{
char
*
fs
=
po
->
fieldSep
;
while
(
*
fs
++
)
*
p
++=
'+'
;
}
}
*
p
=
'\0'
;
if
(
po
->
standard
)
fprintf
(
fout
,
"%s
\n
"
,
border
);
}
if
(
po
->
standard
)
fputs
(
po
->
fieldSep
,
fout
);
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
char
*
s
=
PQfname
(
res
,
j
);
if
(
po
->
html3
)
{
fprintf
(
fout
,
"<th align=%s>%s</th>"
,
fieldNotNum
[
j
]
?
"left"
:
"right"
,
fieldNames
[
j
]);
}
else
{
int
n
=
strlen
(
s
);
if
(
n
>
fieldMax
[
j
])
fieldMax
[
j
]
=
n
;
if
(
po
->
standard
)
fprintf
(
fout
,
fieldNotNum
[
j
]
?
" %-*s "
:
" %*s "
,
fieldMax
[
j
],
s
);
else
fprintf
(
fout
,
fieldNotNum
[
j
]
?
"%-*s"
:
"%*s"
,
fieldMax
[
j
],
s
);
if
(
po
->
standard
||
(
j
+
1
)
<
nFields
)
fputs
(
po
->
fieldSep
,
fout
);
}
}
if
(
po
->
html3
)
fputs
(
"</tr>
\n
"
,
fout
);
else
fprintf
(
fout
,
"
\n
%s
\n
"
,
border
);
}
for
(
i
=
0
;
i
<
nTups
;
i
++
)
{
if
(
po
->
html3
)
fputs
(
"<tr>"
,
fout
);
else
if
(
po
->
standard
)
fputs
(
po
->
fieldSep
,
fout
);
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
char
*
p
=
fields
[
i
*
nFields
+
j
];
if
(
po
->
html3
)
fprintf
(
fout
,
"<td align=%s>%s</td>"
,
fieldNotNum
[
j
]
?
"left"
:
"right"
,
p
?
p
:
""
);
else
{
fprintf
(
fout
,
fieldNotNum
[
j
]
?
(
po
->
standard
?
" %-*s "
:
"%-*s"
)
:
(
po
->
standard
?
" %*s "
:
"%*s"
),
fieldMax
[
j
],
p
?
p
:
""
);
if
(
po
->
standard
||
(
j
+
1
)
<
nFields
)
fputs
(
po
->
fieldSep
,
fout
);
}
if
(
p
)
free
(
p
);
}
if
(
po
->
html3
)
fputs
(
"</tr>"
,
fout
);
else
if
(
po
->
standard
)
fprintf
(
fout
,
"
\n
%s"
,
border
);
fputc
(
'\n'
,
fout
);
}
free
(
fields
);
}
if
(
po
->
header
&&
!
po
->
html3
)
fprintf
(
fout
,
"(%d row%s)
\n\n
"
,
PQntuples
(
res
),
(
PQntuples
(
res
)
==
1
)
?
""
:
"s"
);
free
(
fieldMax
);
free
(
fieldNotNum
);
free
(
fieldNames
);
if
(
usePipe
)
{
pclose
(
fout
);
signal
(
SIGPIPE
,
SIG_DFL
);
}
if
(
border
)
free
(
border
);
if
(
po
->
html3
&&
!
po
->
expanded
)
fputs
(
"</table>
\n
"
,
fout
);
}
}
}
/* ----------------
/* ----------------
*
PQfn - Send a function call to the POSTGRES backend.
*
PQfn - Send a function call to the POSTGRES backend.
*
*
* conn : backend connection
* conn : backend connection
*
fnid
: function id
*
fnid
: function id
*
result_buf : pointer to result buffer (&int if integer)
*
result_buf : pointer to result buffer (&int if integer)
*
result_len
: length of return value.
*
result_len
: length of return value.
* actual_result_len: actual length returned. (differs from result_len
* actual_result_len: actual length returned. (differs from result_len
*
for varlena structures.)
*
for varlena structures.)
* result_type : If the result is an integer, this must be 1,
* result_type : If the result is an integer, this must be 1,
* otherwise this should be 0
* otherwise this should be 0
*
args
: pointer to a NULL terminated arg array.
*
args
: pointer to a NULL terminated arg array.
*
(length, if integer, and result-pointer)
*
(length, if integer, and result-pointer)
*
nargs
: # of arguments in args array.
*
nargs
: # of arguments in args array.
*
*
* RETURNS
* RETURNS
*
NULL on failure. PQerrormsg will be set.
*
NULL on failure. PQerrormsg will be set.
*
"G" if there is a return value.
*
"G" if there is a return value.
*
"V" if there is no return value.
*
"V" if there is no return value.
* ----------------
* ----------------
*/
*/
...
@@ -1260,64 +1299,66 @@ PQfn(PGconn *conn,
...
@@ -1260,64 +1299,66 @@ PQfn(PGconn *conn,
pqPuts
(
"F "
,
pfout
,
pfdebug
);
/* function */
pqPuts
(
"F "
,
pfout
,
pfdebug
);
/* function */
pqPutInt
(
fnid
,
4
,
pfout
,
pfdebug
);
/* function id */
pqPutInt
(
fnid
,
4
,
pfout
,
pfdebug
);
/* function id */
pqPutInt
(
nargs
,
4
,
pfout
,
pfdebug
);
/*
# of args */
pqPutInt
(
nargs
,
4
,
pfout
,
pfdebug
);
/*
# of args */
for
(
i
=
0
;
i
<
nargs
;
++
i
)
{
/*
len.int4 + contents
*/
for
(
i
=
0
;
i
<
nargs
;
++
i
)
{
/*
len.int4 + contents
*/
pqPutInt
(
args
[
i
].
len
,
4
,
pfout
,
pfdebug
);
pqPutInt
(
args
[
i
].
len
,
4
,
pfout
,
pfdebug
);
if
(
args
[
i
].
isint
)
{
if
(
args
[
i
].
isint
)
{
pqPutInt
(
args
[
i
].
u
.
integer
,
4
,
pfout
,
pfdebug
);
pqPutInt
(
args
[
i
].
u
.
integer
,
4
,
pfout
,
pfdebug
);
}
else
{
}
else
{
pqPutnchar
((
char
*
)
args
[
i
].
u
.
ptr
,
args
[
i
].
len
,
pfout
,
pfdebug
);
pqPutnchar
((
char
*
)
args
[
i
].
u
.
ptr
,
args
[
i
].
len
,
pfout
,
pfdebug
);
}
}
}
}
pqFlush
(
pfout
,
pfdebug
);
pqFlush
(
pfout
,
pfdebug
);
id
=
pqGetc
(
pfin
,
pfdebug
);
id
=
pqGetc
(
pfin
,
pfdebug
);
if
(
id
!=
'V'
)
{
if
(
id
!=
'V'
)
{
if
(
id
==
'E'
)
{
if
(
id
==
'E'
)
{
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
);
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
);
}
else
}
else
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"PQfn: expected a 'V' from the backend. Got '%c' instead"
,
"PQfn: expected a 'V' from the backend. Got '%c' instead"
,
id
);
id
);
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
}
}
id
=
pqGetc
(
pfin
,
pfdebug
);
id
=
pqGetc
(
pfin
,
pfdebug
);
for
(;;)
{
for
(;;)
{
int
c
;
int
c
;
switch
(
id
)
{
switch
(
id
)
{
case
'G'
:
/* function returned properly */
case
'G'
:
/* function returned properly */
pqGetInt
(
actual_result_len
,
4
,
pfin
,
pfdebug
);
pqGetInt
(
actual_result_len
,
4
,
pfin
,
pfdebug
);
if
(
result_is_int
)
{
if
(
result_is_int
)
{
pqGetInt
(
result_buf
,
4
,
pfin
,
pfdebug
);
pqGetInt
(
result_buf
,
4
,
pfin
,
pfdebug
);
}
else
{
}
else
{
pqGetnchar
((
char
*
)
result_buf
,
*
actual_result_len
,
pqGetnchar
((
char
*
)
result_buf
,
*
actual_result_len
,
pfin
,
pfdebug
);
pfin
,
pfdebug
);
}
}
c
=
pqGetc
(
pfin
,
pfdebug
);
/* get the last '0'*/
c
=
pqGetc
(
pfin
,
pfdebug
);
/* get the last '0'*/
return
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
return
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
case
'E'
:
case
'E'
:
sprintf
(
conn
->
errorMessage
,
sprintf
(
conn
->
errorMessage
,
"PQfn: returned an error"
);
"PQfn: returned an error"
);
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
case
'N'
:
case
'N'
:
/* print notice and go back to processing return values */
/* print notice and go back to processing return values */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
sprintf
(
conn
->
errorMessage
,
==
1
)
{
"Notice return detected from backend, but error message cannot be read"
);
sprintf
(
conn
->
errorMessage
,
}
else
"Notice return detected from backend, but message "
fprintf
(
stderr
,
"%s
\n
"
,
conn
->
errorMessage
);
"cannot be read"
);
/* keep iterating */
}
else
break
;
fprintf
(
stderr
,
"%s
\n
"
,
conn
->
errorMessage
);
case
'0'
:
/* no return value */
/* keep iterating */
return
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
break
;
default:
case
'0'
:
/* no return value */
/* The backend violates the protocol. */
return
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
sprintf
(
conn
->
errorMessage
,
default:
"FATAL: PQfn: protocol error: id=%x
\n
"
,
id
);
/* The backend violates the protocol. */
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
sprintf
(
conn
->
errorMessage
,
}
"FATAL: PQfn: protocol error: id=%x
\n
"
,
id
);
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
}
}
}
}
}
...
@@ -1366,15 +1407,15 @@ PQfname(PGresult *res, int field_num)
...
@@ -1366,15 +1407,15 @@ PQfname(PGresult *res, int field_num)
}
}
if
(
field_num
>
(
res
->
numAttributes
-
1
))
{
if
(
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"PQfname: ERROR! name of field %d(of %d) is not available"
,
"PQfname: ERROR! name of field %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
);
field_num
,
res
->
numAttributes
-
1
);
return
NULL
;
return
NULL
;
}
}
if
(
res
->
attDescs
)
{
if
(
res
->
attDescs
)
{
return
res
->
attDescs
[
field_num
].
name
;
return
res
->
attDescs
[
field_num
].
name
;
}
else
}
else
return
NULL
;
return
NULL
;
}
}
/*
/*
...
@@ -1412,14 +1453,14 @@ PQftype(PGresult *res, int field_num)
...
@@ -1412,14 +1453,14 @@ PQftype(PGresult *res, int field_num)
}
}
if
(
field_num
>
(
res
->
numAttributes
-
1
))
{
if
(
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"PQftype: ERROR! type of field %d(of %d) is not available"
,
"PQftype: ERROR! type of field %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
);
field_num
,
res
->
numAttributes
-
1
);
}
}
if
(
res
->
attDescs
)
{
if
(
res
->
attDescs
)
{
return
res
->
attDescs
[
field_num
].
adtid
;
return
res
->
attDescs
[
field_num
].
adtid
;
}
else
}
else
return
InvalidOid
;
return
InvalidOid
;
}
}
int2
int2
...
@@ -1431,14 +1472,14 @@ PQfsize(PGresult *res, int field_num)
...
@@ -1431,14 +1472,14 @@ PQfsize(PGresult *res, int field_num)
}
}
if
(
field_num
>
(
res
->
numAttributes
-
1
))
{
if
(
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"PQfsize: ERROR! size of field %d(of %d) is not available"
,
"PQfsize: ERROR! size of field %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
);
field_num
,
res
->
numAttributes
-
1
);
}
}
if
(
res
->
attDescs
)
{
if
(
res
->
attDescs
)
{
return
res
->
attDescs
[
field_num
].
adtsize
;
return
res
->
attDescs
[
field_num
].
adtsize
;
}
else
}
else
return
0
;
return
0
;
}
}
char
*
PQcmdStatus
(
PGresult
*
res
)
{
char
*
PQcmdStatus
(
PGresult
*
res
)
{
...
@@ -1472,7 +1513,7 @@ const char* PQoidStatus(PGresult *res) {
...
@@ -1472,7 +1513,7 @@ const char* PQoidStatus(PGresult *res) {
/*
/*
PQgetvalue:
PQgetvalue:
return the attribute value of field 'field_num' of
return the attribute value of field 'field_num' of
tuple
'tup_num'
row
'tup_num'
If res is binary, then the value returned is NOT a null-terminated
If res is binary, then the value returned is NOT a null-terminated
ASCII string, but the binary representation in the server's native
ASCII string, but the binary representation in the server's native
...
@@ -1489,10 +1530,11 @@ PQgetvalue(PGresult *res, int tup_num, int field_num)
...
@@ -1489,10 +1530,11 @@ PQgetvalue(PGresult *res, int tup_num, int field_num)
}
}
if
(
tup_num
>
(
res
->
ntups
-
1
)
||
if
(
tup_num
>
(
res
->
ntups
-
1
)
||
field_num
>
(
res
->
numAttributes
-
1
))
{
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"PQgetvalue: ERROR! field %d(of %d) of tuple %d(of %d) is not available"
,
"PQgetvalue: ERROR! field %d(of %d) of row %d(of %d) "
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
"is not available"
,
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
}
}
return
res
->
tuples
[
tup_num
][
field_num
].
value
;
return
res
->
tuples
[
tup_num
][
field_num
].
value
;
...
@@ -1512,16 +1554,17 @@ PQgetlength(PGresult *res, int tup_num, int field_num)
...
@@ -1512,16 +1554,17 @@ PQgetlength(PGresult *res, int tup_num, int field_num)
}
}
if
(
tup_num
>
(
res
->
ntups
-
1
)
||
if
(
tup_num
>
(
res
->
ntups
-
1
)
||
field_num
>
(
res
->
numAttributes
-
1
))
{
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"PQgetlength: ERROR! field %d(of %d) of tuple %d(of %d) is not available"
,
"PQgetlength: ERROR! field %d(of %d) of row %d(of %d) "
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
"is not available"
,
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
}
}
if
(
res
->
tuples
[
tup_num
][
field_num
].
len
!=
NULL_LEN
)
if
(
res
->
tuples
[
tup_num
][
field_num
].
len
!=
NULL_LEN
)
return
res
->
tuples
[
tup_num
][
field_num
].
len
;
return
res
->
tuples
[
tup_num
][
field_num
].
len
;
else
else
return
0
;
return
0
;
}
}
/* PQgetisnull:
/* PQgetisnull:
...
@@ -1536,16 +1579,15 @@ PQgetisnull(PGresult *res, int tup_num, int field_num)
...
@@ -1536,16 +1579,15 @@ PQgetisnull(PGresult *res, int tup_num, int field_num)
}
}
if
(
tup_num
>
(
res
->
ntups
-
1
)
||
if
(
tup_num
>
(
res
->
ntups
-
1
)
||
field_num
>
(
res
->
numAttributes
-
1
))
{
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"PQgetisnull: ERROR! field %d(of %d) of tuple %d(of %d) is not available"
,
"PQgetisnull: ERROR! field %d(of %d) of row %d(of %d) "
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
"is not available"
,
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
}
}
if
(
res
->
tuples
[
tup_num
][
field_num
].
len
==
NULL_LEN
)
if
(
res
->
tuples
[
tup_num
][
field_num
].
len
==
NULL_LEN
)
return
1
;
return
1
;
else
else
return
0
;
return
0
;
}
}
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