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 @@
*
*
* 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 {
}
screen_size
;
#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: */
#define TUPARR_GROW_BY 100
...
...
@@ -64,25 +64,25 @@ PQclear(PGresult* res)
int
i
,
j
;
if
(
!
res
)
return
;
return
;
/* free all the
tuple
s */
/* free all the
row
s */
for
(
i
=
0
;
i
<
res
->
ntups
;
i
++
)
{
for
(
j
=
0
;
j
<
res
->
numAttributes
;
j
++
)
{
if
(
res
->
tuples
[
i
][
j
].
value
)
free
(
res
->
tuples
[
i
][
j
].
value
);
}
free
(
res
->
tuples
[
i
]);
for
(
j
=
0
;
j
<
res
->
numAttributes
;
j
++
)
{
if
(
res
->
tuples
[
i
][
j
].
value
)
free
(
res
->
tuples
[
i
][
j
].
value
);
}
free
(
res
->
tuples
[
i
]);
}
free
(
res
->
tuples
);
/* free all the attributes */
for
(
i
=
0
;
i
<
res
->
numAttributes
;
i
++
)
{
if
(
res
->
attDescs
[
i
].
name
)
free
(
res
->
attDescs
[
i
].
name
);
if
(
res
->
attDescs
[
i
].
name
)
free
(
res
->
attDescs
[
i
].
name
);
}
free
(
res
->
attDescs
);
/* free the structure itself */
free
(
res
);
}
...
...
@@ -114,7 +114,7 @@ makeEmptyPGresult(PGconn *conn, ExecStatusType status)
/*
* getTuple -
* get the next
tuple
from the stream
* get the next
row
from the stream
*
* the CALLER is responsible from freeing the PGresAttValue returned
*/
...
...
@@ -127,9 +127,9 @@ getTuple(PGconn *conn, PGresult* result, int binary)
int
bitmap_index
=
0
;
int
i
;
int
nbytes
;
/* the number of bytes in bitmap */
char
bmap
;
/* One byte of the bitmap */
int
bitcnt
=
0
;
/* number of bits examined in current byte */
int
vlen
;
/* length of the current field value */
char
bmap
;
/* One byte of the bitmap */
int
bitcnt
=
0
;
/* number of bits examined in current byte */
int
vlen
;
/* length of the current field value */
FILE
*
pfin
=
conn
->
Pfin
;
FILE
*
pfdebug
=
conn
->
Pfdebug
;
...
...
@@ -147,7 +147,7 @@ getTuple(PGconn *conn, PGresult* result, int binary)
if
(
pqGetnchar
(
bitmap
,
nbytes
,
pfin
,
pfdebug
)
==
1
){
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
;
}
...
...
@@ -155,24 +155,24 @@ getTuple(PGconn *conn, PGresult* result, int binary)
for
(
i
=
0
;
i
<
nfields
;
i
++
)
{
if
(
!
(
bmap
&
0200
))
{
/* if the field value is absent, make it '\0' */
tup
[
i
].
value
=
(
char
*
)
malloc
(
1
);
tup
[
i
].
value
[
0
]
=
'\0'
;
tup
[
i
].
len
=
NULL_LEN
;
/* if the field value is absent, make it '\0' */
tup
[
i
].
value
=
(
char
*
)
malloc
(
1
);
tup
[
i
].
value
[
0
]
=
'\0'
;
tup
[
i
].
len
=
NULL_LEN
;
}
else
{
/* get the value length (the first four bytes are for length) */
pqGetInt
(
&
vlen
,
VARHDRSZ
,
pfin
,
pfdebug
);
if
(
binary
==
0
)
{
vlen
=
vlen
-
VARHDRSZ
;
}
vlen
=
vlen
-
VARHDRSZ
;
}
if
(
vlen
<
0
)
vlen
=
0
;
vlen
=
0
;
tup
[
i
].
len
=
vlen
;
tup
[
i
].
value
=
(
char
*
)
malloc
(
vlen
+
1
);
/* read in the value; */
if
(
vlen
>
0
)
pqGetnchar
((
char
*
)(
tup
[
i
].
value
),
vlen
,
pfin
,
pfdebug
);
pqGetnchar
((
char
*
)(
tup
[
i
].
value
),
vlen
,
pfin
,
pfdebug
);
tup
[
i
].
value
[
vlen
]
=
'\0'
;
}
/* get the appropriate bitmap */
...
...
@@ -191,7 +191,7 @@ getTuple(PGconn *conn, PGresult* result, int binary)
/*
* 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
*
*/
...
...
@@ -204,11 +204,11 @@ addTuple(PGresult* res, PGresAttValue* tup)
if
(
res
->
ntups
==
0
)
res
->
tuples
=
(
PGresAttValue
**
)
malloc
(
res
->
tupArrSize
*
sizeof
(
PGresAttValue
*
));
malloc
(
res
->
tupArrSize
*
sizeof
(
PGresAttValue
*
));
else
/* we can use realloc because shallow copying of the structure is okay */
res
->
tuples
=
(
PGresAttValue
**
)
realloc
(
res
->
tuples
,
res
->
tupArrSize
*
sizeof
(
PGresAttValue
*
));
realloc
(
res
->
tuples
,
res
->
tupArrSize
*
sizeof
(
PGresAttValue
*
));
}
res
->
tuples
[
res
->
ntups
]
=
tup
;
...
...
@@ -217,11 +217,11 @@ addTuple(PGresult* res, PGresAttValue* tup)
/*
* 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
* 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
*
...
...
@@ -249,7 +249,7 @@ makePGresult(PGconn* conn, char* pname)
/* the next two bytes are the number of fields */
if
(
pqGetInt
(
&
nfields
,
2
,
pfin
,
pfdebug
)
==
1
)
{
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
;
}
else
...
...
@@ -267,10 +267,10 @@ makePGresult(PGconn* conn, char* pname)
int
adtsize
;
if
(
pqGets
(
typName
,
MAX_MESSAGE_LEN
,
pfin
,
pfdebug
)
||
pqGetInt
(
&
adtid
,
4
,
pfin
,
pfdebug
)
||
pqGetInt
(
&
adtsize
,
2
,
pfin
,
pfdebug
))
{
pqGetInt
(
&
adtid
,
4
,
pfin
,
pfdebug
)
||
pqGetInt
(
&
adtsize
,
2
,
pfin
,
pfdebug
))
{
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
;
}
result
->
attDescs
[
i
].
name
=
malloc
(
strlen
(
typName
)
+
1
);
...
...
@@ -284,50 +284,49 @@ makePGresult(PGconn* conn, char* pname)
/* process the data stream until we're finished */
while
(
!
done
)
{
switch
(
id
)
{
case
'T'
:
/* a new
tuple
group */
case
'T'
:
/* a new
row
group */
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
;
case
'B'
:
/* a
tuple
in binary format */
case
'D'
:
/* a
tuple
in ASCII format */
case
'B'
:
/* a
row
in binary format */
case
'D'
:
/* a
row
in ASCII format */
newTup
=
getTuple
(
conn
,
result
,
(
id
==
'B'
));
if
(
newTup
==
NULL
)
goto
makePGresult_badResponse_return
;
goto
makePGresult_badResponse_return
;
addTuple
(
result
,
newTup
);
break
;
/* case 'A':
sprintf(conn->errorMessage, "Asynchronous portals not supported");
result->resultStatus = PGRES_NONFATAL_ERROR;
return result;
break;
*/
case
'C'
:
/* end of portal tuple stream */
case
'C'
:
/* end of portal row stream */
{
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
;
}
break
;
case
'E'
:
/* errors */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
"Error return detected from backend, but error message cannot be read"
);
sprintf
(
conn
->
errorMessage
,
"Error return detected from backend, "
"but error message cannot be read"
);
}
result
->
resultStatus
=
PGRES_FATAL_ERROR
;
return
result
;
break
;
case
'N'
:
/* notices from the backend */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
"Notice return detected from backend, but error message cannot be read"
);
}
else
/* XXXX send Notices to stderr for now */
fprintf
(
stderr
,
"%s
\n
"
,
conn
->
errorMessage
);
sprintf
(
conn
->
errorMessage
,
"Notice return detected from backend, "
"but error message cannot be read"
);
}
else
/* XXXX send Notices to stderr for now */
fprintf
(
stderr
,
"%s
\n
"
,
conn
->
errorMessage
);
break
;
default:
/* uh-oh
this should never happen but frequently does when the
backend dumps core */
sprintf
(
conn
->
errorMessage
,
"FATAL: unexpected results from the backend, it probably dumped core."
);
this should never happen but frequently does when the
backend dumps core */
sprintf
(
conn
->
errorMessage
,
"FATAL: unrecognized data from the backend. "
"It probably dumped core."
);
fprintf
(
stderr
,
conn
->
errorMessage
);
result
->
resultStatus
=
PGRES_FATAL_ERROR
;
return
result
;
...
...
@@ -371,7 +370,7 @@ PQexec(PGconn* conn, const char* query)
FILE
*
pfin
,
*
pfout
,
*
pfdebug
;
#ifdef PQ_NOTIFY_PATCH
int
isCommand
=
0
;
/* DZ - 31-8-1996 */
int
isCommand
=
0
;
/* DZ - 31-8-1996 */
#endif
pname
[
0
]
=
'\0'
;
...
...
@@ -409,9 +408,9 @@ PQexec(PGconn* conn, const char* query)
/* send the query to the backend; */
if
(
pqPuts
(
buffer
,
pfout
,
pfdebug
)
==
1
)
{
(
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
"
,
query
,
errno
,
strerror
(
errno
));
query
,
errno
,
strerror
(
errno
));
return
NULL
;
}
...
...
@@ -427,7 +426,7 @@ PQexec(PGconn* conn, const char* query)
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 "
"PQexec() -- Request was sent to backend, but backend "
"closed the channel before "
"responding. This probably means the backend "
"terminated abnormally before or while processing "
...
...
@@ -438,30 +437,31 @@ PQexec(PGconn* conn, const char* query)
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
tuple
s returned */
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
row
s 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
;
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.
*/
clear
=
0
;
error
=
0
;
pqPuts
(
"Q "
,
pfout
,
pfdebug
);
/* send an empty query */
/*
// 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.
*/
clear
=
0
;
error
=
0
;
pqPuts
(
"Q "
,
pfout
,
pfdebug
);
/* send an empty query */
#ifdef PQ_NOTIFY_PATCH
/*
* Set a flag and process messages in the usual way because
...
...
@@ -469,71 +469,71 @@ PQexec(PGconn* conn, const char* query)
*/
isCommand
=
1
;
#else
while
(
!
clear
)
{
if
(
pqGets
(
buffer
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
clear
=
1
;
/*
// Rules can create error messages while we are waiting
// for the 'I'.
*/
if
(
buffer
[
0
]
==
'E'
)
{
strcpy
(
conn
->
errorMessage
,
&
buffer
[
1
]);
error
++
;
}
clear
=
(
buffer
[
0
]
==
'I'
);
}
if
(
error
)
{
return
(
PGresult
*
)
NULL
;
}
result
=
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
strncpy
(
result
->
cmdStatus
,
cmdStatus
,
CMDSTATUS_LEN
-
1
);
return
result
;
while
(
!
clear
)
{
if
(
pqGets
(
buffer
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
clear
=
1
;
/*
// Rules can create error messages while we are waiting
// for the 'I'.
*/
if
(
buffer
[
0
]
==
'E'
)
{
strcpy
(
conn
->
errorMessage
,
&
buffer
[
1
]);
error
++
;
}
clear
=
(
buffer
[
0
]
==
'I'
);
}
if
(
error
)
{
return
(
PGresult
*
)
NULL
;
}
result
=
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
strncpy
(
result
->
cmdStatus
,
cmdStatus
,
CMDSTATUS_LEN
-
1
);
return
result
;
#endif
}
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 error message cannot be read"
);
(
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
);
}
#ifdef PQ_NOTIFY_PATCH
if
(
isCommand
)
{
/*
* 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
;
}
#endif
result
=
makeEmptyPGresult
(
conn
,
PGRES_EMPTY_QUERY
);
return
result
;
int
c
;
if
((
c
=
pqGetc
(
pfin
,
pfdebug
))
!=
'\0'
)
{
fprintf
(
stderr
,
"error!, unexpected character %c following 'I'
\n
"
,
c
);
}
if
(
isCommand
)
{
/*
* 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
;
}
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() -- error return detected from backend, but error message cannot be read"
);
return
(
PGresult
*
)
NULL
;
sprintf
(
conn
->
errorMessage
,
"PQexec() -- Notice detected from backend, "
"but attempt to read the notice failed."
);
return
(
PGresult
*
)
NULL
;
}
else
fprintf
(
stderr
,
"%s"
,
conn
->
errorMessage
);
fprintf
(
stderr
,
"%s"
,
conn
->
errorMessage
);
break
;
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
;
case
'T'
:
/* actual
tuple
results: */
case
'T'
:
/* actual
row
results: */
return
makePGresult
(
conn
,
pname
);
break
;
case
'D'
:
/* copy command began successfully */
...
...
@@ -544,8 +544,8 @@ PQexec(PGconn* conn, const char* query)
break
;
default:
sprintf
(
conn
->
errorMessage
,
"unknown protocol character %c read from backend
\n
"
,
id
);
"unknown protocol character %c read from backend
\n
"
,
id
);
return
(
PGresult
*
)
NULL
;
}
/* switch */
}
/* while (1)*/
...
...
@@ -571,13 +571,13 @@ PQnotifies(PGconn *conn)
if
(
!
conn
)
return
NULL
;
if
(
conn
->
status
!=
CONNECTION_OK
)
return
NULL
;
return
NULL
;
/* RemHead returns NULL if list is empy */
e
=
DLRemHead
(
conn
->
notifyList
);
if
(
e
)
return
(
PGnotify
*
)
DLE_VAL
(
e
);
return
(
PGnotify
*
)
DLE_VAL
(
e
);
else
return
NULL
;
return
NULL
;
}
/*
...
...
@@ -590,12 +590,12 @@ PQnotifies(PGconn *conn)
* the terminating \n (like gets(3)).
*
* RETURNS:
*
EOF if it is detected or invalid arguments are given
*
0 if EOL is reached (i.e., \n has been read)
*
(this is required for backward-compatibility -- this
*
routine used to always return EOF or 0, assuming that
*
the line ended within maxlen bytes.)
*
1 in other cases
*
EOF if it is detected or invalid arguments are given
*
0 if EOL is reached (i.e., \n has been read)
*
(this is required for backward-compatibility -- this
*
routine used to always return EOF or 0, assuming that
*
the line ended within maxlen bytes.)
*
1 in other cases
*/
int
PQgetline
(
PGconn
*
conn
,
char
*
s
,
int
maxlen
)
...
...
@@ -605,22 +605,22 @@ PQgetline(PGconn *conn, char *s, int maxlen)
if
(
!
conn
)
return
EOF
;
if
(
!
conn
->
Pfin
||
!
s
||
maxlen
<=
1
)
return
(
EOF
);
return
(
EOF
);
for
(;
maxlen
>
1
&&
(
c
=
pqGetc
(
conn
->
Pfin
,
conn
->
Pfdebug
))
!=
'\n'
&&
c
!=
EOF
;
--
maxlen
)
{
*
s
++
=
c
;
(
c
=
pqGetc
(
conn
->
Pfin
,
conn
->
Pfdebug
))
!=
'\n'
&&
c
!=
EOF
;
--
maxlen
)
{
*
s
++
=
c
;
}
*
s
=
'\0'
;
if
(
c
==
EOF
)
{
return
(
EOF
);
/* error -- reached EOF before \n */
return
(
EOF
);
/* error -- reached EOF before \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
PQputline
(
PGconn
*
conn
,
const
char
*
s
)
{
if
(
conn
&&
(
conn
->
Pfout
))
{
(
void
)
fputs
(
s
,
conn
->
Pfout
);
fflush
(
conn
->
Pfout
);
(
void
)
fputs
(
s
,
conn
->
Pfout
);
fflush
(
conn
->
Pfout
);
}
}
/*
* PQendcopy
*
called while waiting for the backend to respond with success/failure
*
to a "copy".
*
called while waiting for the backend to respond with success/failure
*
to a "copy".
*
* RETURNS:
*
0 on failure
*
1 on success
*
0 on failure
*
1 on success
*/
int
PQendcopy
(
PGconn
*
conn
)
...
...
@@ -660,26 +660,27 @@ PQendcopy(PGconn *conn)
pfdebug
=
conn
->
Pfdebug
;
if
(
(
id
=
pqGetc
(
pfin
,
pfdebug
))
>
0
)
return
(
0
);
return
(
0
);
switch
(
id
)
{
case
'Z'
:
/* backend finished the copy */
return
(
1
);
return
(
1
);
case
'E'
:
case
'N'
:
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
"Error return detected from backend, but error message cannot be read"
);
}
return
(
0
);
break
;
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
"Error return detected from backend, "
"but attempt to read the message failed."
);
}
return
(
0
);
break
;
default:
(
void
)
sprintf
(
conn
->
errorMessage
,
"FATAL: PQendcopy: protocol error: id=%x
\n
"
,
id
);
fputs
(
conn
->
errorMessage
,
stderr
);
fprintf
(
stderr
,
"resetting connection
\n
"
);
PQreset
(
conn
);
return
(
0
);
(
void
)
sprintf
(
conn
->
errorMessage
,
"FATAL: PQendcopy: protocol error: id=%x
\n
"
,
id
);
fputs
(
conn
->
errorMessage
,
stderr
);
fprintf
(
stderr
,
"resetting connection
\n
"
);
PQreset
(
conn
);
return
(
0
);
}
}
...
...
@@ -706,12 +707,12 @@ fill (int length, int max, char filler, FILE *fp)
*/
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
)
{
#define DEFAULT_FIELD_SEP " "
...
...
@@ -721,14 +722,14 @@ PQdisplayTuples(PGresult *res,
int
fLength
[
MAX_FIELDS
];
if
(
fieldSep
==
NULL
)
fieldSep
=
DEFAULT_FIELD_SEP
;
fieldSep
=
DEFAULT_FIELD_SEP
;
/* Get some useful info about the results */
nFields
=
PQnfields
(
res
);
nTuples
=
PQntuples
(
res
);
if
(
fp
==
NULL
)
fp
=
stdout
;
fp
=
stdout
;
/* Zero the initial field lengths */
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
...
...
@@ -737,47 +738,47 @@ PQdisplayTuples(PGresult *res,
/* Find the max length of each field in the result */
/* will be somewhat time consuming for very large results */
if
(
fillAlign
)
{
for
(
i
=
0
;
i
<
nTuples
;
i
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
if
(
PQgetlength
(
res
,
i
,
j
)
>
fLength
[
j
])
fLength
[
j
]
=
PQgetlength
(
res
,
i
,
j
);
}
}
for
(
i
=
0
;
i
<
nTuples
;
i
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
if
(
PQgetlength
(
res
,
i
,
j
)
>
fLength
[
j
])
fLength
[
j
]
=
PQgetlength
(
res
,
i
,
j
);
}
}
}
if
(
printHeader
)
{
/* first, print out the attribute names */
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
fputs
(
PQfname
(
res
,
i
),
fp
);
if
(
fillAlign
)
fill
(
strlen
(
PQfname
(
res
,
i
)),
fLength
[
i
],
' '
,
fp
);
fputs
(
fieldSep
,
fp
);
}
fprintf
(
fp
,
"
\n
"
);
/* first, print out the attribute names */
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
fputs
(
PQfname
(
res
,
i
),
fp
);
if
(
fillAlign
)
fill
(
strlen
(
PQfname
(
res
,
i
)),
fLength
[
i
],
' '
,
fp
);
fputs
(
fieldSep
,
fp
);
}
fprintf
(
fp
,
"
\n
"
);
/* Underline the attribute names */
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
if
(
fillAlign
)
fill
(
0
,
fLength
[
i
],
'-'
,
fp
);
fputs
(
fieldSep
,
fp
);
}
fprintf
(
fp
,
"
\n
"
);
/* Underline the attribute names */
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
if
(
fillAlign
)
fill
(
0
,
fLength
[
i
],
'-'
,
fp
);
fputs
(
fieldSep
,
fp
);
}
fprintf
(
fp
,
"
\n
"
);
}
/* next, print out the instances */
for
(
i
=
0
;
i
<
nTuples
;
i
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
fprintf
(
fp
,
"%s"
,
PQgetvalue
(
res
,
i
,
j
));
if
(
fillAlign
)
fill
(
strlen
(
PQgetvalue
(
res
,
i
,
j
)),
fLength
[
j
],
' '
,
fp
);
fputs
(
fieldSep
,
fp
);
if
(
fillAlign
)
fill
(
strlen
(
PQgetvalue
(
res
,
i
,
j
)),
fLength
[
j
],
' '
,
fp
);
fputs
(
fieldSep
,
fp
);
}
fprintf
(
fp
,
"
\n
"
);
}
if
(
!
quiet
)
fprintf
(
fp
,
"
\n
Query returned %d row%s.
\n
"
,
PQntuples
(
res
),
(
PQntuples
(
res
)
==
1
)
?
""
:
"s"
);
fprintf
(
fp
,
"
\n
Query returned %d row%s.
\n
"
,
PQntuples
(
res
),
(
PQntuples
(
res
)
==
1
)
?
""
:
"s"
);
fflush
(
fp
);
}
...
...
@@ -792,11 +793,11 @@ PQdisplayTuples(PGresult *res,
*/
void
PQprintTuples
(
PGresult
*
res
,
FILE
*
fout
,
/* output stream */
int
PrintAttNames
,
/* print attribute names or not*/
int
TerseOutput
,
/* delimiter bars or not?*/
int
colWidth
/* width of column, if 0, use variable width */
)
FILE
*
fout
,
/* output stream */
int
PrintAttNames
,
/* print attribute names or not*/
int
TerseOutput
,
/* delimiter bars or not?*/
int
colWidth
/* width of column, if 0, use variable width */
)
{
int
nFields
;
int
nTups
;
...
...
@@ -813,426 +814,464 @@ PQprintTuples(PGresult *res,
}
else
sprintf
(
formatString
,
"%%s %%s"
);
if
(
nFields
>
0
)
{
/* only print tuples with at least 1 field. */
if
(
!
TerseOutput
)
{
int
width
;
width
=
nFields
*
14
;
tborder
=
malloc
(
width
+
1
);
for
(
i
=
0
;
i
<=
width
;
i
++
)
tborder
[
i
]
=
'-'
;
tborder
[
i
]
=
'\0'
;
fprintf
(
fout
,
"%s
\n
"
,
tborder
);
}
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
if
(
PrintAttNames
)
{
fprintf
(
fout
,
formatString
,
TerseOutput
?
""
:
"|"
,
PQfname
(
res
,
i
));
}
}
if
(
PrintAttNames
)
{
if
(
TerseOutput
)
fprintf
(
fout
,
"
\n
"
);
else
fprintf
(
fout
,
"|
\n
%s
\n
"
,
tborder
);
}
for
(
i
=
0
;
i
<
nTups
;
i
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
char
*
pval
=
PQgetvalue
(
res
,
i
,
j
);
fprintf
(
fout
,
formatString
,
TerseOutput
?
""
:
"|"
,
pval
?
pval
:
""
);
}
if
(
TerseOutput
)
fprintf
(
fout
,
"
\n
"
);
else
fprintf
(
fout
,
"|
\n
%s
\n
"
,
tborder
);
}
if
(
nFields
>
0
)
{
/* only print rows with at least 1 field. */
if
(
!
TerseOutput
)
{
int
width
;
width
=
nFields
*
14
;
tborder
=
malloc
(
width
+
1
);
for
(
i
=
0
;
i
<=
width
;
i
++
)
tborder
[
i
]
=
'-'
;
tborder
[
i
]
=
'\0'
;
fprintf
(
fout
,
"%s
\n
"
,
tborder
);
}
for
(
i
=
0
;
i
<
nFields
;
i
++
)
{
if
(
PrintAttNames
)
{
fprintf
(
fout
,
formatString
,
TerseOutput
?
""
:
"|"
,
PQfname
(
res
,
i
));
}
}
if
(
PrintAttNames
)
{
if
(
TerseOutput
)
fprintf
(
fout
,
"
\n
"
);
else
fprintf
(
fout
,
"|
\n
%s
\n
"
,
tborder
);
}
for
(
i
=
0
;
i
<
nTups
;
i
++
)
{
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
char
*
pval
=
PQgetvalue
(
res
,
i
,
j
);
fprintf
(
fout
,
formatString
,
TerseOutput
?
""
:
"|"
,
pval
?
pval
:
""
);
}
if
(
TerseOutput
)
fprintf
(
fout
,
"
\n
"
);
else
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()
*
* new PQprintTuples routine (proff@suburbia.net)
* Format results of a query for printing.
*
* PQprintOpt is a typedef (structure) that containes
* various flags and options. consult libpq-fe.h for
* details
*
* Obsoletes PQprintTuples.
*/
void
PQprint
(
FILE
*
fout
,
PGresult
*
res
,
PQprintOpt
*
po
PQprintOpt
*
po
)
{
int
nFields
;
nFields
=
PQnfields
(
res
);
if
(
nFields
>
0
)
{
/* only print tuples with at least 1 field. */
int
i
,
j
;
int
nTups
;
int
*
fieldMax
=
NULL
;
/* in case we don't use them */
unsigned
char
*
fieldNotNum
=
NULL
;
char
*
border
=
NULL
;
char
**
fields
=
NULL
;
char
**
fieldNames
;
int
fieldMaxLen
=
0
;
int
numFieldName
;
int
fs_len
=
strlen
(
po
->
fieldSep
);
int
total_line_length
=
0
;
int
usePipe
=
0
;
char
*
pagerenv
;
char
buf
[
8192
*
2
+
1
];
nTups
=
PQntuples
(
res
);
if
(
!
(
fieldNames
=
(
char
**
)
calloc
(
nFields
,
sizeof
(
char
*
))))
{
perror
(
"calloc"
);
exit
(
1
);
}
if
(
!
(
fieldNotNum
=
(
unsigned
char
*
)
calloc
(
nFields
,
1
)))
{
perror
(
"calloc"
);
exit
(
1
);
}
if
(
!
(
fieldMax
=
(
int
*
)
calloc
(
nFields
,
sizeof
(
int
))))
{
perror
(
"calloc"
);
exit
(
1
);
}
for
(
numFieldName
=
0
;
po
->
fieldName
&&
po
->
fieldName
[
numFieldName
];
numFieldName
++
)
;
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
int
len
;
char
*
s
=
(
j
<
numFieldName
&&
po
->
fieldName
[
j
][
0
])
?
po
->
fieldName
[
j
]
:
PQfname
(
res
,
j
);
fieldNames
[
j
]
=
s
;
len
=
s
?
strlen
(
s
)
:
0
;
fieldMax
[
j
]
=
len
;
/*
if (po->header && len<5)
len=5;
*/
len
+=
fs_len
;
if
(
len
>
fieldMaxLen
)
fieldMaxLen
=
len
;
total_line_length
+=
len
;
}
if
(
nFields
>
0
)
{
/* only print rows with at least 1 field. */
int
i
,
j
;
int
nTups
;
int
*
fieldMax
=
NULL
;
/* in case we don't use them */
unsigned
char
*
fieldNotNum
=
NULL
;
char
*
border
=
NULL
;
char
**
fields
=
NULL
;
char
**
fieldNames
;
int
fieldMaxLen
=
0
;
int
numFieldName
;
int
fs_len
=
strlen
(
po
->
fieldSep
);
int
total_line_length
=
0
;
int
usePipe
=
0
;
char
*
pagerenv
;
char
buf
[
8192
*
2
+
1
];
nTups
=
PQntuples
(
res
);
if
(
!
(
fieldNames
=
(
char
**
)
calloc
(
nFields
,
sizeof
(
char
*
))))
{
perror
(
"calloc"
);
exit
(
1
);
}
if
(
!
(
fieldNotNum
=
(
unsigned
char
*
)
calloc
(
nFields
,
1
)))
{
perror
(
"calloc"
);
exit
(
1
);
}
if
(
!
(
fieldMax
=
(
int
*
)
calloc
(
nFields
,
sizeof
(
int
))))
{
perror
(
"calloc"
);
exit
(
1
);
}
for
(
numFieldName
=
0
;
po
->
fieldName
&&
po
->
fieldName
[
numFieldName
];
numFieldName
++
)
;
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
int
len
;
char
*
s
=
(
j
<
numFieldName
&&
po
->
fieldName
[
j
][
0
])
?
po
->
fieldName
[
j
]
:
PQfname
(
res
,
j
);
fieldNames
[
j
]
=
s
;
len
=
s
?
strlen
(
s
)
:
0
;
fieldMax
[
j
]
=
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
)
fout
=
stdout
;
if
(
po
->
pager
&&
fout
==
stdout
&&
isatty
(
fileno
(
stdin
))
&&
isatty
(
fileno
(
stdout
)))
{
/* try to pipe to the pager program if possible */
if
(
fout
==
NULL
)
fout
=
stdout
;
if
(
po
->
pager
&&
fout
==
stdout
&&
isatty
(
fileno
(
stdin
))
&&
isatty
(
fileno
(
stdout
)))
{
/* try to pipe to the pager program if possible */
#ifdef TIOCGWINSZ
if
(
ioctl
(
fileno
(
stdout
),
TIOCGWINSZ
,
&
screen_size
)
==
-
1
||
screen_size
.
ws_col
==
0
||
screen_size
.
ws_row
==
0
)
{
if
(
ioctl
(
fileno
(
stdout
),
TIOCGWINSZ
,
&
screen_size
)
==
-
1
||
screen_size
.
ws_col
==
0
||
screen_size
.
ws_row
==
0
)
{
#endif
screen_size
.
ws_row
=
24
;
screen_size
.
ws_col
=
80
;
screen_size
.
ws_row
=
24
;
screen_size
.
ws_col
=
80
;
#ifdef TIOCGWINSZ
}
}
#endif
pagerenv
=
getenv
(
"PAGER"
);
if
(
pagerenv
!=
NULL
&&
pagerenv
[
0
]
!=
'\0'
&&
!
po
->
html3
&&
((
po
->
expanded
&&
nTups
*
(
nFields
+
1
)
>=
screen_size
.
ws_row
)
||
(
!
po
->
expanded
&&
nTups
*
(
total_line_length
/
screen_size
.
ws_col
+
1
)
*
(
1
+
(
po
->
standard
!=
0
))
>=
screen_size
.
ws_row
-
(
po
->
header
!=
0
)
*
(
total_line_length
/
screen_size
.
ws_col
+
1
)
*
2
-
(
po
->
header
!=
0
)
*
2
/* row count and newline */
)))
{
fout
=
popen
(
pagerenv
,
"w"
);
if
(
fout
)
{
usePipe
=
1
;
signal
(
SIGPIPE
,
SIG_IGN
);
}
else
fout
=
stdout
;
}
}
if
(
!
po
->
expanded
&&
(
po
->
align
||
po
->
html3
))
{
if
(
!
(
fields
=
(
char
**
)
calloc
(
nFields
*
(
nTups
+
1
),
sizeof
(
char
*
))))
{
perror
(
"calloc"
);
exit
(
1
);
}
}
else
if
(
po
->
header
&&
!
po
->
html3
)
{
if
(
po
->
expanded
)
{
if
(
po
->
align
)
fprintf
(
fout
,
"%-*s%s Value
\n
"
,
fieldMaxLen
-
fs_len
,
"Field"
,
po
->
fieldSep
);
else
fprintf
(
fout
,
"%s%sValue
\n
"
,
"Field"
,
po
->
fieldSep
);
}
else
{
int
len
=
0
;
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
char
*
s
=
fieldNames
[
j
];
fputs
(
s
,
fout
);
len
+=
strlen
(
s
)
+
fs_len
;
if
((
j
+
1
)
<
nFields
)
fputs
(
po
->
fieldSep
,
fout
);
}
fputc
(
'\n'
,
fout
);
for
(
len
-=
fs_len
;
len
--
;
fputc
(
'-'
,
fout
));
fputc
(
'\n'
,
fout
);
}
}
if
(
po
->
expanded
&&
po
->
html3
)
{
if
(
po
->
caption
)
fprintf
(
fout
,
"<centre><h2>%s</h2></centre>
\n
"
,
po
->
caption
);
else
fprintf
(
fout
,
"<centre><h2>Query retrieved %d tuples * %d fields</h2></centre>
\n
"
,
nTups
,
nFields
);
}
for
(
i
=
0
;
i
<
nTups
;
i
++
)
{
if
(
po
->
expanded
)
{
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
);
}
pagerenv
=
getenv
(
"PAGER"
);
if
(
pagerenv
!=
NULL
&&
pagerenv
[
0
]
!=
'\0'
&&
!
po
->
html3
&&
((
po
->
expanded
&&
nTups
*
(
nFields
+
1
)
>=
screen_size
.
ws_row
)
||
(
!
po
->
expanded
&&
nTups
*
(
total_line_length
/
screen_size
.
ws_col
+
1
)
*
(
1
+
(
po
->
standard
!=
0
))
>=
screen_size
.
ws_row
-
(
po
->
header
!=
0
)
*
(
total_line_length
/
screen_size
.
ws_col
+
1
)
*
2
-
(
po
->
header
!=
0
)
*
2
/* row count and newline */
)))
{
fout
=
popen
(
pagerenv
,
"w"
);
if
(
fout
)
{
usePipe
=
1
;
signal
(
SIGPIPE
,
SIG_IGN
);
}
else
fout
=
stdout
;
}
}
if
(
!
po
->
expanded
&&
(
po
->
align
||
po
->
html3
))
{
if
(
!
(
fields
=
(
char
**
)
calloc
(
nFields
*
(
nTups
+
1
),
sizeof
(
char
*
))))
{
perror
(
"calloc"
);
exit
(
1
);
}
}
else
if
(
po
->
header
&&
!
po
->
html3
)
{
if
(
po
->
expanded
)
{
if
(
po
->
align
)
fprintf
(
fout
,
"%-*s%s Value
\n
"
,
fieldMaxLen
-
fs_len
,
"Field"
,
po
->
fieldSep
);
else
fprintf
(
fout
,
"%s%sValue
\n
"
,
"Field"
,
po
->
fieldSep
);
}
else
{
int
len
=
0
;
for
(
j
=
0
;
j
<
nFields
;
j
++
)
{
char
*
s
=
fieldNames
[
j
];
fputs
(
s
,
fout
);
len
+=
strlen
(
s
)
+
fs_len
;
if
((
j
+
1
)
<
nFields
)
fputs
(
po
->
fieldSep
,
fout
);
}
fputc
(
'\n'
,
fout
);
for
(
len
-=
fs_len
;
len
--
;
fputc
(
'-'
,
fout
));
fputc
(
'\n'
,
fout
);
}
}
if
(
po
->
expanded
&&
po
->
html3
)
{
if
(
po
->
caption
)
fprintf
(
fout
,
"<centre><h2>%s</h2></centre>
\n
"
,
po
->
caption
);
else
fprintf
(
fout
,
"<centre><h2>"
"Query retrieved %d rows * %d fields"
"</h2></centre>
\n
"
,
nTups
,
nFields
);
}
for
(
i
=
0
;
i
<
nTups
;
i
++
)
{
if
(
po
->
expanded
)
{
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
++
)
{
char
*
pval
,
*
p
,
*
o
;
int
plen
;
if
((
plen
=
PQgetlength
(
res
,
i
,
j
))
<
1
||
!
(
pval
=
PQgetvalue
(
res
,
i
,
j
))
||
!*
pval
)
{
if
(
po
->
align
||
po
->
expanded
)
continue
;
goto
efield
;
}
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
);
}
}
}
}
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
);
}
do_field
(
po
,
res
,
i
,
j
,
buf
,
fs_len
,
fields
,
nFields
,
fieldNames
,
fieldNotNum
,
fieldMax
,
fieldMaxLen
,
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 rows * %d fields"
"</caption>
\n
"
,
po
->
tableOpt
?
po
->
tableOpt
:
""
,
nTups
,
nFields
);
}
else
fprintf
(
fout
,
"<table %s>"
,
po
->
tableOpt
?
po
->
tableOpt
:
""
);
}
if
(
po
->
header
)
do_header
(
fout
,
po
,
nFields
,
fieldMax
,
fieldNames
,
fieldNotNum
,
fs_len
,
border
,
res
);
for
(
i
=
0
;
i
<
nTups
;
i
++
)
output_row
(
fout
,
po
,
nFields
,
fields
,
fieldNotNum
,
fieldMax
,
border
,
i
);
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
*
fnid
: function id
*
result_buf : pointer to result buffer (&int if integer)
*
result_len
: length of return value.
*
fnid
: function id
*
result_buf : pointer to result buffer (&int if integer)
*
result_len
: length of return value.
* 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,
* otherwise this should be 0
*
args
: pointer to a NULL terminated arg array.
*
(length, if integer, and result-pointer)
*
nargs
: # of arguments in args array.
*
args
: pointer to a NULL terminated arg array.
*
(length, if integer, and result-pointer)
*
nargs
: # of arguments in args array.
*
* RETURNS
*
NULL on failure. PQerrormsg will be set.
*
"G" if there is a return value.
*
"V" if there is no return value.
*
NULL on failure. PQerrormsg will be set.
*
"G" if there is a return value.
*
"V" if there is no return value.
* ----------------
*/
...
...
@@ -1260,64 +1299,66 @@ PQfn(PGconn *conn,
pqPuts
(
"F "
,
pfout
,
pfdebug
);
/* function */
pqPutInt
(
fnid
,
4
,
pfout
,
pfdebug
);
/* function id */
pqPutInt
(
nargs
,
4
,
pfout
,
pfdebug
);
/*
# of args */
for
(
i
=
0
;
i
<
nargs
;
++
i
)
{
/*
len.int4 + contents
*/
pqPutInt
(
args
[
i
].
len
,
4
,
pfout
,
pfdebug
);
if
(
args
[
i
].
isint
)
{
pqPutInt
(
args
[
i
].
u
.
integer
,
4
,
pfout
,
pfdebug
);
}
else
{
pqPutnchar
((
char
*
)
args
[
i
].
u
.
ptr
,
args
[
i
].
len
,
pfout
,
pfdebug
);
}
pqPutInt
(
nargs
,
4
,
pfout
,
pfdebug
);
/*
# of args */
for
(
i
=
0
;
i
<
nargs
;
++
i
)
{
/*
len.int4 + contents
*/
pqPutInt
(
args
[
i
].
len
,
4
,
pfout
,
pfdebug
);
if
(
args
[
i
].
isint
)
{
pqPutInt
(
args
[
i
].
u
.
integer
,
4
,
pfout
,
pfdebug
);
}
else
{
pqPutnchar
((
char
*
)
args
[
i
].
u
.
ptr
,
args
[
i
].
len
,
pfout
,
pfdebug
);
}
}
pqFlush
(
pfout
,
pfdebug
);
id
=
pqGetc
(
pfin
,
pfdebug
);
if
(
id
!=
'V'
)
{
if
(
id
==
'E'
)
{
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
);
}
else
sprintf
(
conn
->
errorMessage
,
"PQfn: expected a 'V' from the backend. Got '%c' instead"
,
id
);
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
if
(
id
==
'E'
)
{
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
);
}
else
sprintf
(
conn
->
errorMessage
,
"PQfn: expected a 'V' from the backend. Got '%c' instead"
,
id
);
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
}
id
=
pqGetc
(
pfin
,
pfdebug
);
for
(;;)
{
int
c
;
switch
(
id
)
{
case
'G'
:
/* function returned properly */
pqGetInt
(
actual_result_len
,
4
,
pfin
,
pfdebug
);
if
(
result_is_int
)
{
pqGetInt
(
result_buf
,
4
,
pfin
,
pfdebug
);
}
else
{
pqGetnchar
((
char
*
)
result_buf
,
*
actual_result_len
,
pfin
,
pfdebug
);
}
c
=
pqGetc
(
pfin
,
pfdebug
);
/* get the last '0'*/
return
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
case
'E'
:
sprintf
(
conn
->
errorMessage
,
"PQfn: returned an error"
);
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
case
'N'
:
/* print notice and go back to processing return values */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
"Notice return detected from backend, but error message cannot be read"
);
}
else
fprintf
(
stderr
,
"%s
\n
"
,
conn
->
errorMessage
);
/* keep iterating */
break
;
case
'0'
:
/* no return value */
return
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
default:
/* The backend violates the protocol. */
sprintf
(
conn
->
errorMessage
,
"FATAL: PQfn: protocol error: id=%x
\n
"
,
id
);
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
}
int
c
;
switch
(
id
)
{
case
'G'
:
/* function returned properly */
pqGetInt
(
actual_result_len
,
4
,
pfin
,
pfdebug
);
if
(
result_is_int
)
{
pqGetInt
(
result_buf
,
4
,
pfin
,
pfdebug
);
}
else
{
pqGetnchar
((
char
*
)
result_buf
,
*
actual_result_len
,
pfin
,
pfdebug
);
}
c
=
pqGetc
(
pfin
,
pfdebug
);
/* get the last '0'*/
return
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
case
'E'
:
sprintf
(
conn
->
errorMessage
,
"PQfn: returned an error"
);
return
makeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
case
'N'
:
/* print notice and go back to processing return values */
if
(
pqGets
(
conn
->
errorMessage
,
ERROR_MSG_LENGTH
,
pfin
,
pfdebug
)
==
1
)
{
sprintf
(
conn
->
errorMessage
,
"Notice return detected from backend, but message "
"cannot be read"
);
}
else
fprintf
(
stderr
,
"%s
\n
"
,
conn
->
errorMessage
);
/* keep iterating */
break
;
case
'0'
:
/* no return value */
return
makeEmptyPGresult
(
conn
,
PGRES_COMMAND_OK
);
default:
/* The backend violates the protocol. */
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)
}
if
(
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
"PQfname: ERROR! name of field %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
);
return
NULL
;
fprintf
(
stderr
,
"PQfname: ERROR! name of field %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
);
return
NULL
;
}
if
(
res
->
attDescs
)
{
return
res
->
attDescs
[
field_num
].
name
;
return
res
->
attDescs
[
field_num
].
name
;
}
else
return
NULL
;
return
NULL
;
}
/*
...
...
@@ -1412,14 +1453,14 @@ PQftype(PGresult *res, int field_num)
}
if
(
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
"PQftype: ERROR! type of field %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
);
fprintf
(
stderr
,
"PQftype: ERROR! type of field %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
);
}
if
(
res
->
attDescs
)
{
return
res
->
attDescs
[
field_num
].
adtid
;
return
res
->
attDescs
[
field_num
].
adtid
;
}
else
return
InvalidOid
;
return
InvalidOid
;
}
int2
...
...
@@ -1431,14 +1472,14 @@ PQfsize(PGresult *res, int field_num)
}
if
(
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
"PQfsize: ERROR! size of field %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
);
fprintf
(
stderr
,
"PQfsize: ERROR! size of field %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
);
}
if
(
res
->
attDescs
)
{
return
res
->
attDescs
[
field_num
].
adtsize
;
return
res
->
attDescs
[
field_num
].
adtsize
;
}
else
return
0
;
return
0
;
}
char
*
PQcmdStatus
(
PGresult
*
res
)
{
...
...
@@ -1472,7 +1513,7 @@ const char* PQoidStatus(PGresult *res) {
/*
PQgetvalue:
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
ASCII string, but the binary representation in the server's native
...
...
@@ -1489,10 +1530,11 @@ PQgetvalue(PGresult *res, int tup_num, int field_num)
}
if
(
tup_num
>
(
res
->
ntups
-
1
)
||
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
"PQgetvalue: ERROR! field %d(of %d) of tuple %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
"PQgetvalue: ERROR! field %d(of %d) of row %d(of %d) "
"is not available"
,
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
}
return
res
->
tuples
[
tup_num
][
field_num
].
value
;
...
...
@@ -1512,16 +1554,17 @@ PQgetlength(PGresult *res, int tup_num, int field_num)
}
if
(
tup_num
>
(
res
->
ntups
-
1
)
||
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
"PQgetlength: ERROR! field %d(of %d) of tuple %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
"PQgetlength: ERROR! field %d(of %d) of row %d(of %d) "
"is not available"
,
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
}
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
return
0
;
return
0
;
}
/* PQgetisnull:
...
...
@@ -1536,16 +1579,15 @@ PQgetisnull(PGresult *res, int tup_num, int field_num)
}
if
(
tup_num
>
(
res
->
ntups
-
1
)
||
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
"PQgetisnull: ERROR! field %d(of %d) of tuple %d(of %d) is not available"
,
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
field_num
>
(
res
->
numAttributes
-
1
))
{
fprintf
(
stderr
,
"PQgetisnull: ERROR! field %d(of %d) of row %d(of %d) "
"is not available"
,
field_num
,
res
->
numAttributes
-
1
,
tup_num
,
res
->
ntups
);
}
if
(
res
->
tuples
[
tup_num
][
field_num
].
len
==
NULL_LEN
)
return
1
;
return
1
;
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