Skip to content

Commit 73df802

Browse files
boramabyroot
authored andcommitted
Read EOF/OK packets with info message after row data
The 9 byte packet length limit applied at #179 is by itself not sufficient to differentiate between a real EOF/OK packet vs. a huge data packet. The combined EOF/OK packet can be up to max_packet_length long instead. - added an is_eof_packet function with the logic to determine whether a packet starting with an EOF byt is an EOF/OK packet or data - updated the corresponding conditions in row-reading functions
1 parent 7fcfe8c commit 73df802

File tree

3 files changed

+119
-3
lines changed

3 files changed

+119
-3
lines changed

src/client.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,21 @@ static int read_deprecated_eof_packet(trilogy_conn_t *conn)
280280
return TRILOGY_EOF;
281281
}
282282

283+
bool is_eof_packet(trilogy_conn_t *conn)
284+
{
285+
// An EOF packet first byte can mark an EOF/OK packet, a deprecated EOF packet, or a huge data packet.
286+
if (current_packet_type(conn) == TRILOGY_PACKET_EOF) {
287+
if (conn->capabilities & TRILOGY_CAPABILITIES_DEPRECATE_EOF) {
288+
// The EOF/OK packet can contain an info message and/or session state info up to max packet length.
289+
return conn->packet_buffer.len <= TRILOGY_MAX_PACKET_LEN;
290+
} else {
291+
// The deprecated EOF packet must be smaller than 9 bytes (one 8-byte length-encoded integer).
292+
return conn->packet_buffer.len < 9;
293+
}
294+
}
295+
return false;
296+
}
297+
283298
static int read_eof_packet(trilogy_conn_t *conn)
284299
{
285300
int rc;
@@ -983,7 +998,7 @@ int trilogy_read_row(trilogy_conn_t *conn, trilogy_value_t *values_out)
983998
return rc;
984999
}
9851000

986-
if (current_packet_type(conn) == TRILOGY_PACKET_EOF && conn->packet_buffer.len < 9) {
1001+
if (is_eof_packet(conn)) {
9871002
if ((rc = read_eof_packet(conn)) != TRILOGY_OK) {
9881003
return rc;
9891004
}
@@ -1018,7 +1033,7 @@ int trilogy_drain_results(trilogy_conn_t *conn)
10181033
return rc;
10191034
}
10201035

1021-
if (current_packet_type(conn) == TRILOGY_PACKET_EOF && conn->packet_buffer.len < 9) {
1036+
if (is_eof_packet(conn)) {
10221037
read_eof_packet(conn);
10231038
return TRILOGY_OK;
10241039
}
@@ -1261,7 +1276,7 @@ int trilogy_stmt_read_row(trilogy_conn_t *conn, trilogy_stmt_t *stmt, trilogy_co
12611276
return rc;
12621277
}
12631278

1264-
if (current_packet_type(conn) == TRILOGY_PACKET_EOF && conn->packet_buffer.len < 9) {
1279+
if (is_eof_packet(conn)) {
12651280
if ((rc = read_eof_packet(conn)) != TRILOGY_OK) {
12661281
return rc;
12671282
}

test/client/eof_packet_test.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include <stdint.h>
2+
3+
#include "../test.h"
4+
5+
#include "trilogy/client.h"
6+
#include "trilogy/protocol.h"
7+
8+
bool is_eof_packet(trilogy_conn_t *conn);
9+
10+
static int setup_conn_packet(trilogy_conn_t *conn, uint8_t packet_type, size_t packet_len, uint32_t capabilities)
11+
{
12+
int err = trilogy_init(conn);
13+
if (err != TRILOGY_OK) {
14+
return err;
15+
}
16+
17+
conn->packet_buffer.buff[0] = packet_type;
18+
conn->packet_buffer.len = packet_len;
19+
conn->capabilities = capabilities;
20+
21+
return TRILOGY_OK;
22+
}
23+
24+
TEST test_is_eof_packet_no_eof_marker()
25+
{
26+
trilogy_conn_t conn;
27+
28+
int err = setup_conn_packet(&conn, TRILOGY_PACKET_ERR, 1, 0);
29+
ASSERT_OK(err);
30+
31+
ASSERT_EQ(false, is_eof_packet(&conn));
32+
33+
trilogy_free(&conn);
34+
PASS();
35+
}
36+
37+
TEST test_is_eof_packet_deprecated_eof_packet()
38+
{
39+
trilogy_conn_t conn;
40+
41+
int err = setup_conn_packet(&conn, TRILOGY_PACKET_EOF, 8, 0);
42+
ASSERT_OK(err);
43+
44+
ASSERT_EQ(true, is_eof_packet(&conn));
45+
46+
trilogy_free(&conn);
47+
PASS();
48+
}
49+
50+
TEST test_is_eof_packet_data_without_deprecated_eof_support()
51+
{
52+
trilogy_conn_t conn;
53+
54+
int err = setup_conn_packet(&conn, TRILOGY_PACKET_EOF, 9, 0);
55+
ASSERT_OK(err);
56+
57+
ASSERT_EQ(false, is_eof_packet(&conn));
58+
59+
trilogy_free(&conn);
60+
PASS();
61+
}
62+
63+
TEST test_is_eof_packet_max_length_ok_packet_with_eof_marker()
64+
{
65+
trilogy_conn_t conn;
66+
67+
int err = setup_conn_packet(&conn, TRILOGY_PACKET_EOF, TRILOGY_MAX_PACKET_LEN,
68+
TRILOGY_CAPABILITIES_DEPRECATE_EOF);
69+
ASSERT_OK(err);
70+
71+
ASSERT_EQ(true, is_eof_packet(&conn));
72+
73+
trilogy_free(&conn);
74+
PASS();
75+
}
76+
77+
TEST test_is_eof_packet_data_with_deprecated_eof_support()
78+
{
79+
trilogy_conn_t conn;
80+
81+
int err = setup_conn_packet(&conn, TRILOGY_PACKET_EOF, TRILOGY_MAX_PACKET_LEN + 1,
82+
TRILOGY_CAPABILITIES_DEPRECATE_EOF);
83+
ASSERT_OK(err);
84+
85+
ASSERT_EQ(false, is_eof_packet(&conn));
86+
87+
trilogy_free(&conn);
88+
PASS();
89+
}
90+
91+
int client_eof_packet_test()
92+
{
93+
RUN_TEST(test_is_eof_packet_no_eof_marker);
94+
RUN_TEST(test_is_eof_packet_deprecated_eof_packet);
95+
RUN_TEST(test_is_eof_packet_data_without_deprecated_eof_support);
96+
RUN_TEST(test_is_eof_packet_max_length_ok_packet_with_eof_marker);
97+
RUN_TEST(test_is_eof_packet_data_with_deprecated_eof_support);
98+
99+
return 0;
100+
}

test/runner.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const trilogy_sockopt_t *get_connopt(void) { return &connopt; }
4949
SUITE(client_stmt_execute_test) \
5050
SUITE(client_stmt_reset_test) \
5151
SUITE(client_stmt_close_test) \
52+
SUITE(client_eof_packet_test) \
5253

5354
#define XX(name) extern int name();
5455
ALL_SUITES(XX)

0 commit comments

Comments
 (0)