Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
P
postgres-lambda-diff
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jakob Huber
postgres-lambda-diff
Commits
5493ecc3
Commit
5493ecc3
authored
22 years ago
by
Tom Lane
Browse files
Options
Downloads
Patches
Plain Diff
Adjust error-handling logic in libpq. For the first time, libpq copes
sanely with running out of memory for a query result.
parent
90903069
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/interfaces/libpq/fe-exec.c
+25
-12
25 additions, 12 deletions
src/interfaces/libpq/fe-exec.c
with
25 additions
and
12 deletions
src/interfaces/libpq/fe-exec.c
+
25
−
12
View file @
5493ecc3
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.13
5
2003/05/
08 18:16:37
tgl Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.13
6
2003/05/
26 20:05:20
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -55,7 +55,7 @@ static void parseInput(PGconn *conn);
...
@@ -55,7 +55,7 @@ static void parseInput(PGconn *conn);
static
void
handleSendFailure
(
PGconn
*
conn
);
static
void
handleSendFailure
(
PGconn
*
conn
);
static
void
handleSyncLoss
(
PGconn
*
conn
,
char
id
,
int
msgLength
);
static
void
handleSyncLoss
(
PGconn
*
conn
,
char
id
,
int
msgLength
);
static
int
getRowDescriptions
(
PGconn
*
conn
);
static
int
getRowDescriptions
(
PGconn
*
conn
);
static
int
getAnotherTuple
(
PGconn
*
conn
);
static
int
getAnotherTuple
(
PGconn
*
conn
,
int
msgLength
);
static
int
getParameterStatus
(
PGconn
*
conn
);
static
int
getParameterStatus
(
PGconn
*
conn
);
static
int
getNotify
(
PGconn
*
conn
);
static
int
getNotify
(
PGconn
*
conn
);
...
@@ -835,17 +835,28 @@ parseInput(PGconn *conn)
...
@@ -835,17 +835,28 @@ parseInput(PGconn *conn)
}
}
break
;
break
;
case
'D'
:
/* Data Row */
case
'D'
:
/* Data Row */
if
(
conn
->
result
!=
NULL
)
if
(
conn
->
result
!=
NULL
&&
conn
->
result
->
resultStatus
==
PGRES_TUPLES_OK
)
{
{
/* Read another tuple of a normal query response */
/* Read another tuple of a normal query response */
if
(
getAnotherTuple
(
conn
))
if
(
getAnotherTuple
(
conn
,
msgLength
))
return
;
return
;
}
}
else
if
(
conn
->
result
!=
NULL
&&
conn
->
result
->
resultStatus
==
PGRES_FATAL_ERROR
)
{
/*
* We've already choked for some reason. Just discard
* tuples till we get to the end of the query.
*/
conn
->
inCursor
+=
msgLength
;
}
else
else
{
{
snprintf
(
noticeWorkspace
,
sizeof
(
noticeWorkspace
),
/* Set up to report error at end of query */
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"server sent data (
\"
D
\"
message) without prior row description (
\"
T
\"
message)
\n
"
));
libpq_gettext
(
"server sent data (
\"
D
\"
message) without prior row description (
\"
T
\"
message)
\n
"
));
DONOTICE
(
conn
,
noticeWorkspace
);
saveErrorResult
(
conn
);
/* Discard the unexpected message */
/* Discard the unexpected message */
conn
->
inCursor
+=
msgLength
;
conn
->
inCursor
+=
msgLength
;
}
}
...
@@ -888,6 +899,7 @@ parseInput(PGconn *conn)
...
@@ -888,6 +899,7 @@ parseInput(PGconn *conn)
id
);
id
);
/* build an error result holding the error message */
/* build an error result holding the error message */
saveErrorResult
(
conn
);
saveErrorResult
(
conn
);
/* not sure if we will see more, so go to ready state */
conn
->
asyncStatus
=
PGASYNC_READY
;
conn
->
asyncStatus
=
PGASYNC_READY
;
/* Discard the unexpected message */
/* Discard the unexpected message */
conn
->
inCursor
+=
msgLength
;
conn
->
inCursor
+=
msgLength
;
...
@@ -931,6 +943,7 @@ handleSyncLoss(PGconn *conn, char id, int msgLength)
...
@@ -931,6 +943,7 @@ handleSyncLoss(PGconn *conn, char id, int msgLength)
pqsecure_close
(
conn
);
pqsecure_close
(
conn
);
closesocket
(
conn
->
sock
);
closesocket
(
conn
->
sock
);
conn
->
sock
=
-
1
;
conn
->
sock
=
-
1
;
conn
->
asyncStatus
=
PGASYNC_READY
;
/* drop out of GetResult wait loop */
}
}
/*
/*
...
@@ -1023,7 +1036,7 @@ getRowDescriptions(PGconn *conn)
...
@@ -1023,7 +1036,7 @@ getRowDescriptions(PGconn *conn)
*/
*/
static
int
static
int
getAnotherTuple
(
PGconn
*
conn
)
getAnotherTuple
(
PGconn
*
conn
,
int
msgLength
)
{
{
PGresult
*
result
=
conn
->
result
;
PGresult
*
result
=
conn
->
result
;
int
nfields
=
result
->
numAttributes
;
int
nfields
=
result
->
numAttributes
;
...
@@ -1050,12 +1063,11 @@ getAnotherTuple(PGconn *conn)
...
@@ -1050,12 +1063,11 @@ getAnotherTuple(PGconn *conn)
if
(
tupnfields
!=
nfields
)
if
(
tupnfields
!=
nfields
)
{
{
/* Replace partially constructed result with an error result */
/* Replace partially constructed result with an error result */
pqClearAsyncResult
(
conn
);
printfPQExpBuffer
(
&
conn
->
errorMessage
,
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"unexpected field count in D message
\n
"
));
libpq_gettext
(
"unexpected field count in D message
\n
"
));
saveErrorResult
(
conn
);
saveErrorResult
(
conn
);
conn
->
asyncStatus
=
PGASYNC_READY
;
/* Discard the failed message by pretending we read it */
/* Discard the failed message by pretending we read it */
conn
->
inCursor
=
conn
->
inStart
+
5
+
msgLength
;
return
0
;
return
0
;
}
}
...
@@ -1102,14 +1114,15 @@ outOfMemory:
...
@@ -1102,14 +1114,15 @@ outOfMemory:
/*
/*
* we do NOT use saveErrorResult() here, because of the likelihood
* we do NOT use saveErrorResult() here, because of the likelihood
* that there's not enough memory to concatenate messages...
* that there's not enough memory to concatenate messages. Instead,
* discard the old result first to try to win back some memory.
*/
*/
pqClearAsyncResult
(
conn
);
pqClearAsyncResult
(
conn
);
printfPQExpBuffer
(
&
conn
->
errorMessage
,
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"out of memory
\n
"
));
libpq_gettext
(
"out of memory
for query result
\n
"
));
conn
->
result
=
PQmakeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
conn
->
result
=
PQmakeEmptyPGresult
(
conn
,
PGRES_FATAL_ERROR
);
conn
->
asyncStatus
=
PGASYNC_READY
;
/* Discard the failed message by pretending we read it */
/* Discard the failed message by pretending we read it */
conn
->
inCursor
=
conn
->
inStart
+
5
+
msgLength
;
return
0
;
return
0
;
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment