Skip to content

Commit 2e1d668

Browse files
author
Aakash Arayambeth
committed
generate a create view query and populate sqlite engine with a view representing the generic shard
Signed-off-by: Aakash Arayambeth <[email protected]>
1 parent f9c4715 commit 2e1d668

File tree

17 files changed

+236
-35
lines changed

17 files changed

+236
-35
lines changed

bdb/bdb_schemachange.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ int handle_scdone(DB_ENV *dbenv, u_int32_t rectype, llog_scdone_args *scdoneop,
190190
}
191191

192192
if (sctype == rename_table || sctype == alias_table ||
193-
(sctype == add && (strlen(table) + 1 < scdoneop->table.size))) {
193+
((sctype == add || sctype == gen_shard) && (strlen(table) + 1 < scdoneop->table.size))) {
194194
strarg = &table[strlen(table) + 1];
195195
}
196196

db/comdb2.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ static void *purge_old_files_thread(void *arg);
208208
static int lrllinecmp(char *lrlline, char *cmpto);
209209
static void ttrap(struct timer_parm *parm);
210210
int clear_temp_tables(void);
211-
int gen_shard_deserialize_shard(uint32_t *numdbs, char ***dbnames, uint32_t *numcols, char ***columns, char ***shardnames, char *serializedStr);
211+
int gen_shard_deserialize_shard(char **genshard_name, uint32_t *numdbs, char ***dbnames, uint32_t *numcols, char ***columns, char ***shardnames, char *serializedStr);
212212
pthread_key_t comdb2_open_key;
213213

214214
/*---GLOBAL SETTINGS---*/
@@ -250,7 +250,7 @@ int gbl_watchdog_watch_threshold = 60;
250250
int gbl_watchdog_disable_at_start = 0; /* don't enable watchdog on start */
251251
int gbl_nonames = 1;
252252
int gbl_reject_osql_mismatch = 1;
253-
int gbl_abort_on_clear_inuse_rqid = 1;
253+
int gbl_abort_on_clear_inuse_rqid = 0;
254254
int gbl_archive_on_init = 1;
255255

256256
pthread_t gbl_invalid_tid; /* set this to our main threads tid */
@@ -2299,7 +2299,7 @@ int llmeta_load_genshards(struct dbenv *dbenv, void *tran) {
22992299
int bdberr = 0;
23002300
/* allow as many generic sharded tables as regular tables (?) */
23012301
char *tablenames[MAX_NUM_TABLES];
2302-
char *shard_info = NULL;
2302+
char *shard_info = NULL, *genshard_name = NULL;
23032303
char **dbnames = NULL, **columns = NULL, **shardnames = NULL;
23042304
int table_count = 0, size = 0;
23052305
uint32_t numdbs=0, numcols=0;
@@ -2322,14 +2322,15 @@ int llmeta_load_genshards(struct dbenv *dbenv, void *tran) {
23222322
goto err;
23232323
}
23242324

2325-
if (gen_shard_deserialize_shard(&numdbs, &dbnames, &numcols, &columns, &shardnames, shard_info)) {
2325+
if (gen_shard_deserialize_shard(&genshard_name, &numdbs, &dbnames, &numcols, &columns, &shardnames, shard_info)) {
23262326
logmsg(LOGMSG_ERROR, "Failed to deserialize llmeta str for generic shard %s\n", tablenames[i]);
23272327
}
23282328

23292329
for(int i=0;i<numdbs;i++){
23302330
db = get_dbtable_by_name(shardnames[i]);
23312331
if (db) {
23322332
/*update the table object*/
2333+
db->genshard_name = genshard_name;
23332334
db->numdbs = numdbs;
23342335
db->dbnames = dbnames;
23352336
db->numcols = numcols;

db/comdb2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ typedef struct dbtable {
791791
const char *timepartition_name;
792792

793793
/* generic sharding metadata */
794+
char *genshard_name;
794795
uint32_t numdbs;
795796
char **dbnames;
796797
uint32_t numcols;

db/gen_shard.c

Lines changed: 169 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ int cson_extract_int(cson_object *cson_obj, const char *param,
1515
struct errstat *err);
1616
cson_array *cson_extract_array(cson_object *cson_obj, const char *param,
1717
struct errstat *err);
18+
int views_sqlite_del_view(const char *view_name, sqlite3 *db,
19+
struct errstat *err);
20+
char *describe_row(const char *tblname, const char *prefix,
21+
enum views_trigger_op op_type, struct errstat *err);
22+
23+
24+
1825
int gen_shard_serialize_shard(const char *tablename, uint32_t numdbs, char **dbnames, uint32_t numcols,
1926
char **columns, char **shardnames, uint32_t *outLen, char **out)
2027
{
@@ -165,11 +172,11 @@ int gen_shard_llmeta_read(void *tran, const char *name, char **pstr)
165172
return rc;
166173
}
167174

168-
int gen_shard_deserialize_shard(uint32_t *numdbs, char ***dbnames, uint32_t *numcols, char ***columns, char ***shardnames, char *serializedStr) {
175+
int gen_shard_deserialize_shard(char **genshard_name, uint32_t *numdbs, char ***dbnames, uint32_t *numcols, char ***columns, char ***shardnames, char *serializedStr) {
169176
cson_object *rootObj = NULL;
170177
cson_value *rootVal = NULL, *arrVal = NULL;
171178
cson_array *dbs_arr = NULL, *cols_arr = NULL, *shards_arr = NULL;
172-
const char *tablename = NULL;
179+
char *tablename = NULL;
173180
char **dbs = NULL, **cols = NULL, **shards = NULL;
174181
char *err_str = NULL;
175182
int num_dbs = 0, num_cols = 0;
@@ -186,7 +193,7 @@ int gen_shard_deserialize_shard(uint32_t *numdbs, char ***dbnames, uint32_t *num
186193
rc = cson_value_is_object(rootVal);
187194
rootObj = cson_value_get_object(rootVal);
188195

189-
tablename = cson_extract_str(rootObj, "TABLENAME", &err);
196+
tablename = (char *)cson_extract_str(rootObj, "TABLENAME", &err);
190197
if (!tablename) {
191198
err_str = "INVALID CSON. Couldn't find 'TABLENAME' key";
192199
goto error;
@@ -262,7 +269,7 @@ int gen_shard_deserialize_shard(uint32_t *numdbs, char ***dbnames, uint32_t *num
262269
}
263270
shards[i] = strdup(cson_value_get_cstr(arrVal));
264271
}
265-
272+
*genshard_name = tablename;
266273
*numdbs = num_dbs;
267274
*dbnames = dbs;
268275
*numcols = num_cols;
@@ -308,21 +315,22 @@ int gen_shard_deserialize_shard(uint32_t *numdbs, char ***dbnames, uint32_t *num
308315
int gen_shard_update_inmem_db(void *tran, struct dbtable *db, const char *name) {
309316
char *serializedStr = NULL;
310317
uint32_t numdbs = 0, numcols = 0;
311-
char **dbnames = NULL, **columns = NULL, **shardnames = NULL;
318+
char **dbnames = NULL, **columns = NULL, **shardnames = NULL, *genshard_name = NULL;
312319
int rc = 0;
313320
rc = gen_shard_llmeta_read(tran, name, &serializedStr);
314321
if (rc) {
315322
logmsg(LOGMSG_ERROR, "Failed to read from llmeta for table %s\n", name);
316323
goto done;
317324
}
318325

319-
rc = gen_shard_deserialize_shard(&numdbs, &dbnames, &numcols, &columns, &shardnames, serializedStr);
326+
rc = gen_shard_deserialize_shard(&genshard_name,&numdbs, &dbnames, &numcols, &columns, &shardnames, serializedStr);
320327
if (rc) {
321328
logmsg(LOGMSG_ERROR, "Failed to deserialized llmeta str for table %s\n", name);
322329
goto done;
323330
}
324331

325332
/*update the table object*/
333+
db->genshard_name = genshard_name;
326334
db->numdbs = numdbs;
327335
db->dbnames = dbnames;
328336
db->numcols = numcols;
@@ -335,4 +343,159 @@ int gen_shard_update_inmem_db(void *tran, struct dbtable *db, const char *name)
335343
return rc;
336344
}
337345

346+
char *gen_shard_create_view_query(struct dbtable *tbl, sqlite3 *db, struct errstat *err)
347+
{
348+
char *select_str = NULL;
349+
char *cols_str = NULL;
350+
char *tmp_str = NULL;
351+
char *ret_str = NULL;
352+
int numshards = tbl->numdbs;
353+
const char *viewname = tbl->genshard_name;
354+
char **dbnames = tbl->dbnames;
355+
char **shardnames = tbl->shardnames;
356+
int i;
357+
cols_str = sqlite3_mprintf("rowid as __hidden__rowid, ");
358+
if (!cols_str) {
359+
goto malloc;
360+
}
361+
362+
cols_str = describe_row(tbl->tablename, cols_str, VIEWS_TRIGGER_QUERY, err);
363+
if (!cols_str) {
364+
/* preserve error, if any */
365+
if (err->errval != VIEW_NOERR)
366+
return NULL;
367+
goto malloc;
368+
} else {
369+
logmsg(LOGMSG_USER, "GOT cols_str as %s\n", cols_str);
370+
}
371+
372+
select_str = sqlite3_mprintf("");
373+
i = 0;
374+
logmsg(LOGMSG_USER, "num shards is : %d\n", numshards);
375+
for(;i<numshards;i++){
376+
tmp_str = sqlite3_mprintf("%s%sSELECT %s FROM %s.'\%s'", select_str, (i > 0) ? " UNION ALL " : "", cols_str,
377+
dbnames[i], shardnames[i]);
378+
sqlite3_free(select_str);
379+
if (!tmp_str) {
380+
sqlite3_free(cols_str);
381+
goto malloc;
382+
}
383+
select_str = tmp_str;
384+
}
385+
386+
ret_str = sqlite3_mprintf("CREATE VIEW %w AS %s", viewname, select_str);
387+
if (!ret_str) {
388+
sqlite3_free(select_str);
389+
sqlite3_free(cols_str);
390+
goto malloc;
391+
}
392+
393+
sqlite3_free(select_str);
394+
sqlite3_free(cols_str);
395+
396+
logmsg(LOGMSG_USER, "THE GENERATED VIEW QUERY IS %s\n", ret_str);
397+
//dbg_verbose_sqlite("Generated:\n\"%s\"\n", ret_str);
398+
399+
return ret_str;
400+
401+
malloc:
402+
err->errval = VIEW_ERR_MALLOC;
403+
snprintf(err->errstr, sizeof(err->errstr), "View %s out of memory\n", viewname);
404+
return NULL;
405+
}
406+
407+
int gen_shard_run_sql(sqlite3 *db, char *stmt, struct errstat *err)
408+
{
409+
char *errstr = NULL;
410+
int rc;
411+
412+
/* create the view */
413+
rc = sqlite3_exec(db, stmt, NULL, NULL, &errstr);
414+
if (rc != SQLITE_OK) {
415+
err->errval = VIEW_ERR_BUG;
416+
snprintf(err->errstr, sizeof(err->errstr), "Sqlite error \"%s\"", errstr);
417+
/* can't control sqlite errors */
418+
err->errstr[sizeof(err->errstr) - 1] = '\0';
419+
420+
logmsg(LOGMSG_USER, "%s: sqlite error \"%s\" sql \"%s\"\n", __func__, errstr, stmt);
421+
422+
if (errstr)
423+
sqlite3_free(errstr);
424+
return err->errval;
425+
}
426+
427+
return VIEW_NOERR;
428+
}
429+
430+
int gen_shard_add_view(struct dbtable *tbl, sqlite3 *db, struct errstat *err)
431+
{
432+
char *stmt_str;
433+
int rc;
434+
435+
/* create the statement */
436+
stmt_str = gen_shard_create_view_query(tbl, db, err);
437+
if (!stmt_str) {
438+
return err->errval;
439+
}
440+
441+
rc = gen_shard_run_sql(db, stmt_str, err);
442+
443+
logmsg(LOGMSG_USER, "+++++++++++sql: %s, rc: %d\n", stmt_str, rc);
444+
/* free the statement */
445+
sqlite3_free(stmt_str);
446+
447+
if (rc != VIEW_NOERR) {
448+
return err->errval;
449+
}
450+
return rc;
451+
}
452+
453+
int gen_shard_delete_view(struct dbtable *tbl, sqlite3 *db, struct errstat *err)
454+
{
455+
return views_sqlite_del_view(tbl->genshard_name, db, err);
456+
}
457+
458+
int gen_shard_update_sqlite(sqlite3 *db, struct errstat *err)
459+
{
460+
Table *tab;
461+
int rc;
462+
for (int tbl_idx = 0; tbl_idx < thedb->num_dbs; ++tbl_idx) {
463+
struct dbtable *tbl = thedb->dbs[tbl_idx];
464+
if (tbl->genshard_name) {
465+
/* this table is a component shard of a genshard table*/
466+
tab = sqlite3FindTableCheckOnly(db, tbl->genshard_name, NULL);
467+
if (tab) {
468+
/* found view, is it the same version ? */
469+
if (tbl->tableversion != tab->version) {
470+
/* older version, destroy current view */
471+
rc = gen_shard_delete_view(tbl, db, err);
472+
if (rc != VIEW_NOERR) {
473+
logmsg(LOGMSG_ERROR, "%s: failed to remove old view\n", __func__);
474+
goto done;
475+
}
476+
} else {
477+
/* up to date, nothing to do */
478+
continue;
479+
}
480+
}
481+
rc = gen_shard_add_view(tbl, db, err);
482+
if (rc != VIEW_NOERR) {
483+
goto done;
484+
}
485+
}
486+
}
487+
rc = VIEW_NOERR;
488+
done:
489+
return rc;
490+
}
491+
492+
int is_gen_shard(const char *tablename) {
493+
for(int i=0;i<thedb->num_dbs;i++) {
494+
struct dbtable *tbl = thedb->dbs[i];
495+
if (tbl->genshard_name && strcmp(tbl->genshard_name, tablename)==0) {
496+
return 1;
497+
}
498+
}
499+
return 0;
500+
}
338501

db/gen_shard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@ int gen_shard_llmeta_add(tran_type *tran, char *tablename, uint32_t numdbs, char
44
uint32_t numcols, char **columns, char **shardnames, struct errstat *);
55
int gen_shard_update_inmem_db(void *tran, struct dbtable *db, const char *name);
66
int gen_shard_llmeta_remove(tran_type *tran, char *tablename, struct errstat *err);
7+
int gen_shard_update_sqlite(sqlite3 *db, struct errstat *err);
8+
int gen_shard_delete_view(struct dbtable *tbl, sqlite3 *db, struct errstat *err);
9+
int gen_shard_add_view(struct dbtable *tbl, sqlite3 *db, struct errstat *err);
10+
int is_gen_shard(const char *tablename);
711
#endif

db/sqlinterfaces.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
#include <net_appsock.h>
114114
#include <typessql.h>
115115
#include <sqlwriter.h>
116-
116+
#include "gen_shard.h"
117117
/*
118118
** WARNING: These enumeration values are not arbitrary. They represent
119119
** indexes into the array of meta-command names contained in
@@ -4300,6 +4300,12 @@ static int prepare_engine(struct sqlthdstate *thd, struct sqlclntstate *clnt,
43004300
}
43014301
}
43024302

4303+
rc = gen_shard_update_sqlite(thd->sqldb, &xerr);
4304+
if (rc) {
4305+
logmsg(LOGMSG_FATAL, "Failed to create views for generic shards."
4306+
"rc=%d errstr=%s\n", xerr.errval, xerr.errstr);
4307+
abort();
4308+
}
43034309
/* save the views generation number */
43044310
thd->views_gen = gbl_views_gen;
43054311
}

db/tag.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6154,6 +6154,7 @@ void freedb_int(dbtable *db, dbtable *replace)
61546154
int i;
61556155
int dbs_idx;
61566156
char *sqlaliasname = db->sqlaliasname;
6157+
char *genshard_name = db->genshard_name;
61576158
const char *timepartition_name = db->timepartition_name;
61586159
char **dbnames = alloca(sizeof(char*) * db->numdbs);
61596160
for (i = 0; i < db->numdbs; i++)
@@ -6167,6 +6168,7 @@ void freedb_int(dbtable *db, dbtable *replace)
61676168

61686169
if (!replace) {
61696170
free(sqlaliasname);
6171+
free(genshard_name);
61706172
for (i = 0; i < db->numdbs; i++) {
61716173
free(dbnames[i]);
61726174
}
@@ -6242,6 +6244,7 @@ void freedb_int(dbtable *db, dbtable *replace)
62426244
db->dbs_idx = dbs_idx;
62436245
db->sqlaliasname = sqlaliasname;
62446246
db->timepartition_name = timepartition_name;
6247+
db->genshard_name = genshard_name;
62456248
for (i = 0; i < db->numdbs; i++)
62466249
db->dbnames[i] = dbnames[i];
62476250
for (i = 0; i < db->numcols; i++)

db/views.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static int _views_do_op(timepart_views_t *views, const char *name,
9797
int (*op)(timepart_views_t *, timepart_view_t *,
9898
struct errstat *),
9999
struct errstat *err);
100-
static char *_describe_row(const char *tblname, const char *prefix,
100+
char *describe_row(const char *tblname, const char *prefix,
101101
enum views_trigger_op op_type, struct errstat *err);
102102
static void *timepart_cron_kickoff(struct cron_event *_, struct errstat *err);
103103
static int _next_shard_exists(timepart_view_t *view, char *newShardName,
@@ -1439,7 +1439,7 @@ int timepart_dump_timepartitions(FILE *dest)
14391439
return has_tp;
14401440
}
14411441

1442-
static char *_describe_row(const char *tblname, const char *prefix,
1442+
char *describe_row(const char *tblname, const char *prefix,
14431443
enum views_trigger_op op_type, struct errstat *err)
14441444
{
14451445
struct dbtable *gdb;

db/views.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ int views_sqlite_add_view(timepart_view_t *view, sqlite3 *db,
217217
*
218218
*
219219
*/
220-
int views_sqlite_del_view(timepart_view_t *view, sqlite3 *db,
220+
int views_sqlite_del_timepart_view(timepart_view_t *view, sqlite3 *db,
221221
struct errstat *err);
222222

223223
/**

0 commit comments

Comments
 (0)