Skip to content

Commit 0adb17c

Browse files
committed
fix(database): preserve Postgre prepared SQLSTATE
- Execute prepared statements through the send/get-result flow - Classify Postgre prepared failures from structured SQLSTATE diagnostics Signed-off-by: memleakd <121398829+memleakd@users.noreply.github.com>
1 parent fb4c345 commit 0adb17c

1 file changed

Lines changed: 32 additions & 12 deletions

File tree

system/Database/Postgre/PreparedQuery.php

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,31 +92,51 @@ public function _execute(array $data): bool
9292
}
9393
}
9494

95-
$this->result = pg_execute($this->db->connID, $this->name, $data);
95+
$sent = pg_send_execute($this->db->connID, $this->name, $data);
9696

97-
if ($this->result instanceof PgSqlResult && pg_result_status($this->result) === PGSQL_FATAL_ERROR) {
98-
$sqlstate = (string) pg_result_error_field($this->result, PGSQL_DIAG_SQLSTATE);
99-
$this->errorCode = 0;
100-
$this->errorString = (string) pg_result_error($this->result);
101-
$this->databaseException = $this->db->createDatabaseException($this->errorString, $sqlstate);
102-
103-
if ($this->db->DBDebug) {
104-
throw $this->databaseException;
105-
}
97+
if ($sent === false || $sent === 0) {
98+
$this->errorCode = 0;
99+
$this->errorString = pg_last_error($this->db->connID);
106100

107101
return false;
108102
}
109103

104+
$this->result = pg_get_result($this->db->connID);
105+
110106
if ($this->result === false) {
111107
$this->errorCode = 0;
112108
$this->errorString = pg_last_error($this->db->connID);
113109

110+
return false;
111+
}
112+
113+
$lastResult = $this->result;
114+
$failedResult = pg_result_status($this->result) === PGSQL_FATAL_ERROR ? $this->result : null;
115+
116+
while (($next = pg_get_result($this->db->connID)) !== false) {
117+
$lastResult = $next;
118+
119+
if (! $failedResult instanceof PgSqlResult && pg_result_status($next) === PGSQL_FATAL_ERROR) {
120+
$failedResult = $next;
121+
}
122+
}
123+
124+
$this->result = $lastResult;
125+
126+
if ($failedResult instanceof PgSqlResult) {
127+
$sqlstate = (string) pg_result_error_field($failedResult, PGSQL_DIAG_SQLSTATE);
128+
$this->errorCode = 0;
129+
$this->errorString = (string) pg_result_error($failedResult);
130+
$this->databaseException = $this->db->createDatabaseException($this->errorString, $sqlstate);
131+
114132
if ($this->db->DBDebug) {
115-
throw $this->db->createDatabaseException($this->errorString, $this->errorCode);
133+
throw $this->databaseException;
116134
}
135+
136+
return false;
117137
}
118138

119-
return (bool) $this->result;
139+
return true;
120140
}
121141

122142
/**

0 commit comments

Comments
 (0)