EV-ClickHouse
view release on metacpan or search on metacpan
xs/proto_native_parse.c view on Meta::CPAN
if (rc == 0) {
/* need more data */
return;
}
if (rc == -2) {
/* object destroyed inside callback */
return;
}
if (rc == 4) {
/* ServerHello received â send addendum (revision >= 54458) */
if (self->native_state == NATIVE_WAIT_HELLO) {
/* Addendum: quota_key (only if server supports it) */
if (self->server_revision >= DBMS_MIN_PROTOCOL_VERSION_WITH_ADDENDUM) {
native_buf_t ab;
nbuf_init(&ab);
nbuf_cstring(&ab, ""); /* quota_key */
send_replace(self, ab.data, ab.len);
if (try_write(self)) return;
if (self->send_pos < self->send_len) {
/* Addendum partially written (EAGAIN); io_cb finishes
* connect once the buffer drains, otherwise pipeline_advance
* could overwrite the unsent tail with a queued query. */
self->pending_addendum_finish = 1;
return;
}
}
self->native_state = NATIVE_IDLE;
if (finish_connect(self)) return;
}
/* pipeline_advance -> try_write may free self; no data
* in recv_buf for the just-dispatched request yet */
return;
}
if (rc == -1) {
/* Stream corruption: native packets aren't length-delimited,
* so resync is impossible â the server's remaining output
* for this query would be misattributed to the next one.
* Tear down; auto_reconnect re-establishes an idle link. */
if (self->native_state == NATIVE_WAIT_HELLO) {
/* Skip auto_reconnect on a malformed ServerHello: the peer
* isn't a ClickHouse server, so retrying just spins.
* (connect_timeout still uses fail_connection, which retries.) */
teardown_io_error(self, errmsg, "connection failed");
Safefree(errmsg);
return;
}
fail_connection(self, errmsg);
Safefree(errmsg);
return;
}
if (rc == 5) {
/* Server exception â a normal query error with its bytes
* consumed, so the stream stays in sync: deliver to the
* query callback and pipeline the next query. */
if (self->native_state == NATIVE_WAIT_HELLO) {
/* The server rejected the handshake itself (e.g. wrong
* credentials) â fail fast with the real text, to
* on_error and to any pre-connect queued queries. No
* reconnect: retrying a rejected handshake just spins. */
teardown_io_error(self, errmsg, errmsg);
Safefree(errmsg);
return;
}
stop_timing(self);
CLEAR_SV(self->native_rows);
CLEAR_INSERT(self);
CLEAR_STR(self->insert_err);
self->native_state = NATIVE_IDLE;
self->cancel_after_meta = 0;
self->cancelled = 0;
self->recv_len = 0; /* drop this dead query's tail, if coalesced */
if (self->send_count > 0) self->send_count--;
lc_free_dicts(self);
int destroyed = deliver_error(self, errmsg);
Safefree(errmsg);
if (destroyed) return;
/* advance pipeline â may free self via try_write error */
pipeline_advance(self);
return;
}
if (rc == 2) {
/* EndOfStream â deliver accumulated rows or deferred error */
stop_timing(self);
self->native_state = NATIVE_IDLE;
self->cancel_after_meta = 0;
CLEAR_INSERT(self);
if (self->send_count > 0) self->send_count--;
lc_free_dicts(self);
/* Flush any uncoalesced progress accumulated since the last
* fire so users instrumenting via on_progress see the full
* total when the query completes within one progress_period
* of the last fire. */
if (self->on_progress && self->progress_period > 0) {
int any = 0, i;
for (i = 0; i < 5; i++) if (self->progress_acc[i]) { any = 1; break; }
if (any) {
uint64_t pp[5];
memcpy(pp, self->progress_acc, sizeof(pp));
memset(self->progress_acc, 0, sizeof(self->progress_acc));
if (fire_progress_cb(self, pp) < 0) return;
}
}
if (self->insert_err) {
char *err = self->insert_err;
self->insert_err = NULL;
CLEAR_SV(self->native_rows);
int destroyed = deliver_error(self, err);
Safefree(err);
if (destroyed) return;
} else if (self->cancelled) {
self->cancelled = 0;
CLEAR_SV(self->native_rows);
( run in 1.653 second using v1.01-cache-2.11-cpan-3f962061493 )