Skip to content

Commit b4d3ab9

Browse files
committed
temp commit: implements 'IN'
1 parent 0e63366 commit b4d3ab9

File tree

6 files changed

+145
-44
lines changed

6 files changed

+145
-44
lines changed

handlersocket/database.cpp

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,35 @@ dbcontext::cmd_sql_internal(dbcallback_i& cb, const prep_stmt& pst,
694694
return cb.dbcb_resp_short(2, "notimpl");
695695
}
696696

697+
static size_t
698+
prepare_keybuf(const cmd_exec_args& args, uchar *key_buf, TABLE *table,
699+
KEY& kinfo, size_t invalues_index)
700+
{
701+
size_t kplen_sum = 0;
702+
DBG_KEY(fprintf(stderr, "SLOW\n"));
703+
for (size_t i = 0; i < args.kvalslen; ++i) {
704+
const KEY_PART_INFO & kpt = kinfo.key_part[i];
705+
string_ref kval = args.kvals[i];
706+
if (args.invalues_keypart >= 0 &&
707+
static_cast<size_t>(args.invalues_keypart) == i) {
708+
kval = args.invalues[invalues_index];
709+
}
710+
if (kval.begin() == 0) {
711+
kpt.field->set_null();
712+
} else {
713+
kpt.field->set_notnull();
714+
}
715+
kpt.field->store(kval.begin(), kval.size(), &my_charset_bin);
716+
kplen_sum += kpt.store_length;
717+
DBG_KEYLEN(fprintf(stderr, "l=%u sl=%zu\n", kpt.length,
718+
kpt.store_length));
719+
}
720+
key_copy(key_buf, table->record[0], &kinfo, kplen_sum);
721+
DBG_KEYLEN(fprintf(stderr, "sum=%zu flen=%u\n", kplen_sum,
722+
kinfo.key_length));
723+
return kplen_sum;
724+
}
725+
697726
void
698727
dbcontext::cmd_find_internal(dbcallback_i& cb, const prep_stmt& pst,
699728
ha_rkey_function find_flag, const cmd_exec_args& args)
@@ -738,26 +767,8 @@ dbcontext::cmd_find_internal(dbcallback_i& cb, const prep_stmt& pst,
738767
return cb.dbcb_resp_short(2, "kpnum");
739768
}
740769
uchar *const key_buf = DENA_ALLOCA_ALLOCATE(uchar, kinfo.key_length);
741-
size_t kplen_sum = 0;
742-
{
743-
DBG_KEY(fprintf(stderr, "SLOW\n"));
744-
for (size_t i = 0; i < args.kvalslen; ++i) {
745-
const KEY_PART_INFO & kpt = kinfo.key_part[i];
746-
const string_ref& kval = args.kvals[i];
747-
if (kval.begin() == 0) {
748-
kpt.field->set_null();
749-
} else {
750-
kpt.field->set_notnull();
751-
}
752-
kpt.field->store(kval.begin(), kval.size(), &my_charset_bin);
753-
kplen_sum += kpt.store_length;
754-
DBG_KEYLEN(fprintf(stderr, "l=%u sl=%zu\n", kpt.length,
755-
kpt.store_length));
756-
}
757-
key_copy(key_buf, table->record[0], &kinfo, kplen_sum);
758-
DBG_KEYLEN(fprintf(stderr, "sum=%zu flen=%u\n", kplen_sum,
759-
kinfo.key_length));
760-
}
770+
size_t invalues_idx = 0;
771+
size_t kplen_sum = prepare_keybuf(args, key_buf, table, kinfo, invalues_idx);
761772
/* filters */
762773
uchar *filter_buf = 0;
763774
if (args.filters != 0) {
@@ -787,8 +798,17 @@ dbcontext::cmd_find_internal(dbcallback_i& cb, const prep_stmt& pst,
787798
uint32_t skip = args.skip;
788799
size_t modified_count = 0;
789800
int r = 0;
790-
for (uint32_t i = 0; i < limit + skip; ++i) {
791-
if (i == 0) {
801+
bool is_first = true;
802+
for (uint32_t cnt = 0; cnt < limit + skip;) {
803+
if (is_first) {
804+
is_first = false;
805+
const key_part_map kpm = (1U << args.kvalslen) - 1;
806+
r = hnd->index_read_map(table->record[0], key_buf, kpm, find_flag);
807+
} else if (args.invalues_keypart >= 0) {
808+
if (++invalues_idx >= args.invalueslen) {
809+
break;
810+
}
811+
kplen_sum = prepare_keybuf(args, key_buf, table, kinfo, invalues_idx);
792812
const key_part_map kpm = (1U << args.kvalslen) - 1;
793813
r = hnd->index_read_map(table->record[0], key_buf, kpm, find_flag);
794814
} else {
@@ -826,12 +846,17 @@ dbcontext::cmd_find_internal(dbcallback_i& cb, const prep_stmt& pst,
826846
} else if (skip > 0) {
827847
--skip;
828848
} else {
849+
/* hit */
829850
if (need_resp_record) {
830851
resp_record(cb, table, pst);
831852
}
832853
if (mod_op != 0) {
833854
r = modify_record(cb, table, pst, args, mod_op, modified_count);
834855
}
856+
++cnt;
857+
}
858+
if (args.invalues_keypart >= 0 && r == HA_ERR_KEY_NOT_FOUND) {
859+
continue;
835860
}
836861
if (r != 0 && r != HA_ERR_RECORD_DELETED) {
837862
break;

handlersocket/database.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,11 @@ struct cmd_exec_args {
103103
string_ref mod_op;
104104
const string_ref *uvals; /* size must be pst->retfieelds.size() */
105105
const record_filter *filters;
106+
int invalues_keypart;
107+
const string_ref *invalues;
108+
size_t invalueslen;
106109
cmd_exec_args() : pst(0), kvals(0), kvalslen(0), limit(0), skip(0),
107-
uvals(0), filters(0) { }
110+
uvals(0), filters(0), invalues_keypart(-1), invalues(0), invalueslen(0) { }
108111
};
109112

110113
struct dbcontext_i {

handlersocket/hstcpsvr_worker.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ struct hstcpsvr_worker : public hstcpsvr_worker_i, private noncopyable {
266266
#endif
267267
bool accept_enabled;
268268
int accept_balance;
269+
std::vector<string_ref> invalues_work;
269270
std::vector<record_filter> filters_work;
270271
private:
271272
int run_one_nb();
@@ -781,8 +782,36 @@ hstcpsvr_worker::do_exec_on_index(char *cmd_begin, char *cmd_end, char *start,
781782
/* simple query */
782783
return dbctx->cmd_exec(conn, args);
783784
}
784-
/* has filters or modops */
785+
/* has more options */
785786
skip_one(start, finish);
787+
/* in-clause */
788+
if (start[0] == '@') {
789+
read_token(start, finish); /* '@' */
790+
skip_one(start, finish);
791+
args.invalues_keypart = read_ui32(start, finish);
792+
skip_one(start, finish);
793+
args.invalueslen = read_ui32(start, finish);
794+
if (args.invalueslen <= 0) {
795+
return conn.dbcb_resp_short(2, "invalueslen");
796+
}
797+
if (invalues_work.size() < args.invalueslen) {
798+
invalues_work.resize(args.invalueslen);
799+
}
800+
args.invalues = &invalues_work[0];
801+
for (uint32_t i = 0; i < args.invalueslen; ++i) {
802+
skip_one(start, finish);
803+
char *const invalue_begin = start;
804+
read_token(start, finish);
805+
char *const invalue_end = start;
806+
char *wp = invalue_begin;
807+
unescape_string(wp, invalue_begin, invalue_end);
808+
invalues_work[i] = string_ref(invalue_begin, wp - invalue_begin);
809+
}
810+
}
811+
if (start == finish) {
812+
/* no more options */
813+
return dbctx->cmd_exec(conn, args);
814+
}
786815
/* filters */
787816
size_t filters_count = 0;
788817
while (start != finish && (start[0] == 'W' || start[0] == 'F')) {

libhsclient/hstcpcli.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ struct hstcpcli : public hstcpcli_i, private noncopyable {
4545
virtual void request_buf_exec_generic(size_t pst_id, const string_ref& op,
4646
const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
4747
const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
48-
const hstcpcli_filter *fils, size_t filslen);
48+
const hstcpcli_filter *fils, size_t filslen, int invalues_keypart,
49+
const string_ref *invalues, size_t invalueslen);
4950
virtual int request_send();
5051
virtual int response_recv(size_t& num_flds_r);
5152
virtual const string_ref *get_next_row();
@@ -218,7 +219,8 @@ void
218219
hstcpcli::request_buf_exec_generic(size_t pst_id, const string_ref& op,
219220
const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
220221
const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
221-
const hstcpcli_filter *fils, size_t filslen)
222+
const hstcpcli_filter *fils, size_t filslen, int invalues_keypart,
223+
const string_ref *invalues, size_t invalueslen)
222224
{
223225
if (num_req_sent > 0 || num_req_rcvd > 0) {
224226
close();
@@ -234,13 +236,26 @@ hstcpcli::request_buf_exec_generic(size_t pst_id, const string_ref& op,
234236
const string_ref& kv = kvs[i];
235237
append_delim_value(writebuf, kv.begin(), kv.end());
236238
}
237-
if (limit != 0 || skip != 0 || mod_op.size() != 0 || filslen != 0) {
239+
if (limit != 0 || skip != 0 || invalues_keypart >= 0 ||
240+
mod_op.size() != 0 || filslen != 0) {
241+
/* has more option */
238242
writebuf.append_literal("\t");
239243
append_uint32(writebuf, limit); // FIXME size_t ?
240-
if (skip != 0 || mod_op.size() != 0 || filslen != 0) {
244+
if (skip != 0 || invalues_keypart >= 0 ||
245+
mod_op.size() != 0 || filslen != 0) {
241246
writebuf.append_literal("\t");
242247
append_uint32(writebuf, skip); // FIXME size_t ?
243248
}
249+
if (invalues_keypart >= 0) {
250+
writebuf.append_literal("\t@\t");
251+
append_uint32(writebuf, invalues_keypart);
252+
writebuf.append_literal("\t");
253+
append_uint32(writebuf, invalueslen);
254+
for (size_t i = 0; i < invalueslen; ++i) {
255+
const string_ref& s = invalues[i];
256+
append_delim_value(writebuf, s.begin(), s.end());
257+
}
258+
}
244259
for (size_t i = 0; i < filslen; ++i) {
245260
const hstcpcli_filter& f = fils[i];
246261
writebuf.append_literal("\t");

libhsclient/hstcpcli.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ struct hstcpcli_i {
4343
virtual void request_buf_exec_generic(size_t pst_id, const string_ref& op,
4444
const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
4545
const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
46-
const hstcpcli_filter *fils = 0, size_t filslen = 0) = 0;
46+
const hstcpcli_filter *fils = 0, size_t filslen = 0,
47+
int invalues_keypart = -1, const string_ref *invalues = 0,
48+
size_t invalueslen = 0) = 0; // FIXME: too long
4749
virtual int request_send() = 0;
4850
virtual int response_recv(size_t& num_flds_r) = 0;
4951
virtual const string_ref *get_next_row() = 0;

0 commit comments

Comments
 (0)