diff --git a/cdb2api/cdb2api.c b/cdb2api/cdb2api.c index b99b151284..2d9f64dd2c 100644 --- a/cdb2api/cdb2api.c +++ b/cdb2api/cdb2api.c @@ -325,6 +325,7 @@ static int refresh_gbl_events_on_hndl(cdb2_hndl_tp *); static int cdb2_get_dbhosts(cdb2_hndl_tp *); static void hndl_set_comdb2buf(cdb2_hndl_tp *, COMDB2BUF *, int idx); static int send_reset(COMDB2BUF *sb, int localcache); +static void free_raw_response(cdb2_hndl_tp *hndl); static int check_hb_on_blocked_write = 0; // temporary switch - this will be default behavior static int check_hb_on_blocked_write_set_from_env = 0; @@ -1484,7 +1485,11 @@ void cdb2_set_sockpool(const char *sp_path) SOCKPOOL_OTHER_NAME = strdup(sp_path); } -static int is_valid_int(const char *str) +#ifndef CDB2API_SERVER +static +#endif + int + cdb2_is_valid_int(const char *str) { while (*str) { if (!isdigit(*str)) @@ -1582,7 +1587,7 @@ static void parse_dbhosts_from_env(int *dbnum, int *num_hosts, char hosts[][CDB2 if (tok == NULL) { return; } - if (is_valid_int(tok)) { + if (cdb2_is_valid_int(tok)) { *dbnum = atoi(tok); tok = strtok_r(NULL, " :,", &last); } @@ -1758,7 +1763,7 @@ static void read_comdb2db_cfg(cdb2_hndl_tp *hndl, COMDB2BUF *s, const char *comd } if (comdb2db_name && strcasecmp(comdb2db_name, tok) == 0) { tok = strtok_r(NULL, " :,", &last); - if (tok && is_valid_int(tok)) { + if (tok && cdb2_is_valid_int(tok)) { *comdb2db_num = atoi(tok); tok = strtok_r(NULL, " :,", &last); } @@ -1778,7 +1783,7 @@ static void read_comdb2db_cfg(cdb2_hndl_tp *hndl, COMDB2BUF *s, const char *comd CDB2DBCONFIG_ADDL_PATH[sizeof(CDB2DBCONFIG_ADDL_PATH) - 1] = '\0'; } } else { /* host list */ - if (tok && is_valid_int(tok)) { + if (tok && cdb2_is_valid_int(tok)) { *dbnum = atoi(tok); tok = strtok_r(NULL, " :,", &last); } @@ -1854,7 +1859,7 @@ static void read_comdb2db_cfg(cdb2_hndl_tp *hndl, COMDB2BUF *s, const char *comd for (ii = 0; ii <= current_size; ii++) cdb2_room_distance[ii] = INT_MAX; while (tok != NULL) { - if (!is_valid_int(tok)) + if (!cdb2_is_valid_int(tok)) break; ii = atoi(tok); if (ii == 0) { @@ -1870,7 +1875,7 @@ static void read_comdb2db_cfg(cdb2_hndl_tp *hndl, COMDB2BUF *s, const char *comd } tok = strtok_r(NULL, " ,", &last); - if (tok && is_valid_int(tok)) + if (tok && cdb2_is_valid_int(tok)) distance = atoi(tok); else continue; @@ -1897,7 +1902,7 @@ static void read_comdb2db_cfg(cdb2_hndl_tp *hndl, COMDB2BUF *s, const char *comd cdb2_alarm_unread_socket_data = value_on_off(tok, &err); } else if (!cdb2_max_discard_records_set_from_env && (strcasecmp("max_discard_records", tok) == 0)) { tok = strtok_r(NULL, " =:,", &last); - if (tok && is_valid_int(tok)) + if (tok && cdb2_is_valid_int(tok)) cdb2_max_discard_records = atoi(tok); } else if (!cdb2_flat_col_vals_set_from_env && strcasecmp("flat_col_vals", tok) == 0) { if ((tok = strtok_r(NULL, " =:,", &last)) != NULL) @@ -4614,6 +4619,10 @@ static int cdb2_send_query(cdb2_hndl_tp *hndl, cdb2_hndl_tp *event_hndl, COMDB2B #if _LINUX_SOURCE sqlquery.little_endian = 1; #endif + if (hndl && hndl->is_tagged) { + sqlquery.has_is_tagged = 1; + sqlquery.is_tagged = 1; + } sqlquery.n_bindvars = n_bindvars; sqlquery.bindvars = bindvars; @@ -5191,7 +5200,9 @@ int cdb2_close(cdb2_hndl_tp *hndl) newsql_disconnect(hndl, hndl->sb, __LINE__); if (hndl->firstresponse) { - cdb2__sqlresponse__free_unpacked(hndl->firstresponse, NULL); + free_raw_response(hndl); + if (hndl->firstresponse) + cdb2__sqlresponse__free_unpacked(hndl->firstresponse, NULL); hndl->firstresponse = NULL; free((void *)hndl->first_buf); hndl->first_buf = NULL; @@ -6005,6 +6016,17 @@ static void attach_to_handle(cdb2_hndl_tp *child, cdb2_hndl_tp *parent) } } +static void free_raw_response(cdb2_hndl_tp *hndl) +{ + // Tagged requests receive a RESPONSE_HEADER__SQL_RESPONSE_RAW response that + // contains both the "header" and the row data. So the first response is + // also the last response and we only need to free one. + if (hndl->is_tagged && hndl->firstresponse && hndl->firstresponse == hndl->lastresponse) { + cdb2__sqlresponse__free_unpacked(hndl->firstresponse, NULL); + hndl->firstresponse = hndl->lastresponse = NULL; + } +} + static void pb_alloc_heuristic(cdb2_hndl_tp *hndl) { if (!cdb2_protobuf_heuristic) @@ -8273,6 +8295,11 @@ static int get_connection_int(cdb2_hndl_tp *hndl, int *err) if (get_dbinfo || *err) return -1; before_discovery(hndl); + if (strcmp(hndl->type, "configured") == 0 && hndl->num_hosts > 0) { + // Special setting of "configured" means the proxy generated a list of hosts in its config and we should + // use that. Don't try discovery or sockpool - use what's in the proxy config. + return 0; + } COMDB2BUF *sb = sockpool_get(hndl); after_discovery(hndl); if (sb == NULL) @@ -8827,6 +8854,8 @@ int cdb2_open(cdb2_hndl_tp **handle, const char *dbname, const char *type, hndl->connected_host = -1; hndl->send_stack = 0; hndl->read_intrans_results = 1; + hndl->is_admin = (flags & CDB2_ADMIN); + hndl->is_tagged = (flags & CDB2_SET_TAGGED); /* We don't do dbinfo if DIRECT_CPU. So we'd default peer SSL mode to ALLOW. We will find it out later when we send SSL negotitaion packet @@ -8836,8 +8865,6 @@ int cdb2_open(cdb2_hndl_tp **handle, const char *dbname, const char *type, hndl->max_retries = MAX_RETRIES; hndl->min_retries = MIN_RETRIES; - hndl->is_admin = (flags & CDB2_ADMIN); - if (cdb2_use_env_vars) { hndl->db_default_type_override_env = 0; hndl->sockpool_enabled = 0; diff --git a/cdb2api/cdb2api.h b/cdb2api/cdb2api.h index 1f7d0d711d..ee3c701d40 100644 --- a/cdb2api/cdb2api.h +++ b/cdb2api/cdb2api.h @@ -42,7 +42,8 @@ enum cdb2_hndl_alloc_flags { #endif CDB2_REQUIRE_FASTSQL = 512, CDB2_MASTER = 1024, - CDB2_ALLOW_INCOHERENT = 2048 + CDB2_ALLOW_INCOHERENT = 2048, + CDB2_SET_TAGGED = 4096 }; enum cdb2_request_type { diff --git a/cdb2api/cdb2api_hndl.h b/cdb2api/cdb2api_hndl.h index 4becb7f045..abef09ff44 100644 --- a/cdb2api/cdb2api_hndl.h +++ b/cdb2api/cdb2api_hndl.h @@ -236,5 +236,6 @@ struct cdb2_hndl { CDB2SQLQUERY__IdentityBlob *id_blob; struct cdb2_stmt_types *stmt_types; RETRY_CALLBACK retry_clbk; + int is_tagged; }; #endif diff --git a/cdb2api/cdb2api_int.h b/cdb2api/cdb2api_int.h index e5a50a447f..29dc7a162a 100644 --- a/cdb2api/cdb2api_int.h +++ b/cdb2api/cdb2api_int.h @@ -52,6 +52,7 @@ void cdb2_hndl_set_min_retries(cdb2_hndl_tp *hndl, int min_retries); int cdb2_get_comdb2db(char **comdb2db_name, char **comdb2db_class); void cdb2_set_debug_trace(cdb2_hndl_tp *hndl); +int cdb2_is_valid_int(const char *str); #endif struct cdb2_identity {