Skip to content

Commit a0dce40

Browse files
committed
fix remote table version 0 regression
Signed-off-by: Dorin Hogea <dhogea@bloomberg.net>
1 parent da7c92c commit a0dce40

File tree

4 files changed

+48
-43
lines changed

4 files changed

+48
-43
lines changed

db/comdb2.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3707,7 +3707,7 @@ int is_tablename_queue(const char *);
37073707

37083708
int rename_table_options(void *tran, struct dbtable *db, const char *newname);
37093709

3710-
int comdb2_get_verify_remote_schemas(void);
3710+
int comdb2_get_verify_remote_schemas(struct sqlclntstate *clnt);
37113711
void comdb2_set_verify_remote_schemas(void);
37123712

37133713
const char *thrman_get_where(struct thr_handle *thr);

db/fdb_fend.c

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,7 @@ enum table_status {
680680
* - TABLE_MISSING, otherwise
681681
*
682682
* !!NOTE!!: only calls this when tables_mtx is acquired
683+
* NOTE2: remote_version is -1ULL if not retrieved
683684
*/
684685
static fdb_tbl_t *_table_exists(fdb_t *fdb, const char *table_name, enum table_status *status, int *version,
685686
unsigned long long remote_version)
@@ -700,7 +701,7 @@ static fdb_tbl_t *_table_exists(fdb_t *fdb, const char *table_name, enum table_s
700701
(table->version != (table->need_version - 1))) {
701702
*status = TABLE_STALE;
702703
} else {
703-
if (table->version != remote_version) {
704+
if (remote_version != -1ULL && table->version != remote_version) {
704705
logmsg(LOGMSG_WARN,
705706
"Remote table %s.%s new version is "
706707
"%lld, cached %lld\n",
@@ -718,7 +719,7 @@ static fdb_tbl_t *_table_exists(fdb_t *fdb, const char *table_name, enum table_s
718719
}
719720

720721
/**
721-
* Expend _table_exists to handle the case when table exist but it is stale;
722+
* Expand _table_exists to handle the case when the table exist but is stale;
722723
* in this case, we unlink the existing table (and free it if no users)/
723724
* //!!NOTE!!: only calls this when tables_mtx is acquired
724725
*/
@@ -865,12 +866,12 @@ void _remove_table_stat(fdb_t *fdb, fdb_tbl_t *tbl, const char *stat_name)
865866
static int _add_table_and_stats_fdb(sqlclntstate *clnt, sqlite3InitInfo *init, fdb_t *fdb, const char *table_name,
866867
int *version)
867868
{
868-
unsigned long long remote_version = 0ULL;
869+
unsigned long long remote_version = -1ULL;
869870
struct errstat err = {0};
870871
int rc = FDB_NOERR;
871872
fdb_tbl_t *tbl = NULL, *stat1 = NULL, *stat4 = NULL;
872873
int initial;
873-
fdb_tbl_ent_t *found_ent;
874+
fdb_tbl_ent_t *found_ent = NULL;
874875
int link_table = 0, link_stat1 = 0, link_stat4 = 0;
875876
int is_sqlite_master; /* corner case when sqlite_master is the first query remote;
876877
there is no "sqlite_master" entry for sqlite_master, but
@@ -893,10 +894,11 @@ static int _add_table_and_stats_fdb(sqlclntstate *clnt, sqlite3InitInfo *init, f
893894
init->locked_stat4 = NULL;
894895
init->fdb = NULL;
895896

896-
/* we need the remote version of the table to be attached, do it now before
897-
* mutexes are acquired (ignore sqlite_master)
897+
/* this is the case when a column is not found, and we assume that it is missing
898+
* from local cache; retrieve remote table version to check for that
899+
* (sqlite_master has no version)
898900
*/
899-
if (comdb2_get_verify_remote_schemas() && !is_sqlite_master) {
901+
if (comdb2_get_verify_remote_schemas(clnt) && !is_sqlite_master) {
900902
/* this is a retry for an already */
901903
rc = fdb_get_remote_version(fdb->dbname, table_name, fdb->class, fdb->loc == NULL, &remote_version, &err);
902904
if (rc != FDB_NOERR) {
@@ -948,7 +950,6 @@ static int _add_table_and_stats_fdb(sqlclntstate *clnt, sqlite3InitInfo *init, f
948950
/* this COULD be taken out of tbls_mtx, but I want to clear table
949951
under lock so I don't add garbage table structures when mispelling
950952
*/
951-
found_ent = NULL;
952953
rc = _retrieve_fdb_tbl(fdb, tbl, initial);
953954

954955
/* lock the tables_mtx again, check if the table was added already
@@ -957,7 +958,11 @@ static int _add_table_and_stats_fdb(sqlclntstate *clnt, sqlite3InitInfo *init, f
957958
*/
958959
Pthread_mutex_lock(&fdb->tables_mtx);
959960

960-
fdb_tbl_t *remtbl = _table_exists_and_not_stale(fdb, table_name, version, remote_version);
961+
/* we have retrieved that table and its version; use that here instead of remote_version
962+
* to check for the corner case when someone already added the table, and it is
963+
* already stale
964+
*/
965+
fdb_tbl_t *remtbl = _table_exists_and_not_stale(fdb, table_name, version, tbl->version);
961966
if (remtbl) {
962967
/* table was already added with the right version */
963968
_free_fdb_tbl(fdb, tbl);
@@ -984,16 +989,17 @@ static int _add_table_and_stats_fdb(sqlclntstate *clnt, sqlite3InitInfo *init, f
984989

985990
if (rc != FDB_NOERR || (!found_ent && !is_sqlite_master)) {
986991
*version = 0;
987-
/* we cannot find the table; remove fdb_tbl, not linked in yet */
988-
_free_fdb_tbl(fdb, tbl);
989-
tbl = NULL;
990992

991993
if (rc == FDB_NOERR) {
992994
logmsg(LOGMSG_ERROR, "%s: unable to find schema for %s.%s rc =%d\n", __func__, fdb->dbname, tbl->name, rc);
993995

994996
rc = FDB_ERR_FDB_TBL_NOTFOUND;
995997
}
996998

999+
/* we cannot find the table; remove fdb_tbl, not linked in yet */
1000+
_free_fdb_tbl(fdb, tbl);
1001+
tbl = NULL;
1002+
9971003
goto done;
9981004
}
9991005

@@ -4582,32 +4588,38 @@ static void _clear_schema(const char *dbname, const char *tblname, int force)
45824588
{
45834589
fdb_t *fdb;
45844590
fdb_tbl_t *tbl;
4591+
int locked = 0;
45854592

45864593
Pthread_mutex_lock(&fdbs.arr_mtx);
45874594

45884595
/* map name to fdb */
45894596
fdb = _cache_fnd_fdb(dbname, NULL);
45904597
if (!fdb) {
45914598
logmsg(LOGMSG_ERROR, "unknown fdb \"%s\"\n", dbname);
4592-
goto done;
4593-
}
4594-
4595-
/* are there any readers of this fdb */
4596-
if (force) {
4597-
if (gbl_fdb_track_locking)
4598-
logmsg(LOGMSG_USER, "Writelock fdb %s schema clean\n", fdb->dbname);
4599-
Pthread_rwlock_wrlock(&fdb->inuse_rwlock);
4600-
if (_test_trap_dlock1 == 2) {
4601-
_test_trap_dlock1++;
4602-
}
46034599
} else {
4604-
if (gbl_fdb_track_locking)
4605-
logmsg(LOGMSG_USER, "Trywrlock fdb %s schema clean\n", fdb->dbname);
4606-
if (pthread_rwlock_trywrlock(&fdb->inuse_rwlock) != 0) {
4607-
logmsg(LOGMSG_ERROR, "there are still readers for this fdb, cancel clear");
4608-
goto done;
4600+
/* are there any readers of this fdb */
4601+
if (force) {
4602+
if (gbl_fdb_track_locking)
4603+
logmsg(LOGMSG_USER, "Writelock fdb %s schema clean\n", fdb->dbname);
4604+
Pthread_rwlock_wrlock(&fdb->inuse_rwlock);
4605+
if (_test_trap_dlock1 == 2) {
4606+
_test_trap_dlock1++;
4607+
}
4608+
locked = 1;
4609+
} else {
4610+
if (gbl_fdb_track_locking)
4611+
logmsg(LOGMSG_USER, "Trywrlock fdb %s schema clean\n", fdb->dbname);
4612+
if (pthread_rwlock_trywrlock(&fdb->inuse_rwlock) != 0) {
4613+
logmsg(LOGMSG_ERROR, "there are still readers for this fdb, cancel clear");
4614+
} else {
4615+
locked = 1;
4616+
}
46094617
}
46104618
}
4619+
Pthread_mutex_unlock(&fdbs.arr_mtx);
4620+
4621+
if (!locked)
4622+
return;
46114623

46124624
/* all ours, lets clear the entries */
46134625
if (tblname == NULL) {
@@ -4623,17 +4635,15 @@ static void _clear_schema(const char *dbname, const char *tblname, int force)
46234635
if (tbl == NULL) {
46244636
logmsg(LOGMSG_ERROR, "Unknown table \"%s\" in db \"%s\"\n", tblname,
46254637
dbname);
4626-
goto unlock;
4638+
} else {
4639+
_unlink_fdb_table(fdb, tbl);
4640+
_free_fdb_tbl(fdb, tbl);
46274641
}
4628-
_unlink_fdb_table(fdb, tbl);
4629-
_free_fdb_tbl(fdb, tbl);
46304642
}
4631-
unlock:
4643+
46324644
if (gbl_fdb_track_locking)
46334645
logmsg(LOGMSG_USER, "Unlock fdb %s schema clean\n", fdb->dbname);
46344646
pthread_rwlock_unlock(&fdb->inuse_rwlock);
4635-
done:
4636-
Pthread_mutex_unlock(&fdbs.arr_mtx);
46374647
}
46384648

46394649
/**

db/sqlglue.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13059,14 +13059,9 @@ void comdb2_set_verify_remote_schemas(void)
1305913059
}
1306013060
}
1306113061

13062-
int comdb2_get_verify_remote_schemas(void)
13062+
int comdb2_get_verify_remote_schemas(struct sqlclntstate *clnt)
1306313063
{
13064-
struct sql_thread *thd = pthread_getspecific(query_info_key);
13065-
13066-
if (thd && thd->clnt)
13067-
return thd->clnt->verify_remote_schemas == 1;
13068-
13069-
return 0;
13064+
return clnt ? clnt->verify_remote_schemas == 1 : 0;
1307013065
}
1307113066

1307213067
uint16_t stmt_num_tbls(sqlite3_stmt *stmt)

db/sqlinterfaces.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3332,7 +3332,7 @@ static int get_prepared_stmt_int(struct sqlthdstate *thd,
33323332
clnt->in_sqlite_init = 0;
33333333
if (rc == SQLITE_OK) {
33343334
if (!prepareOnly) rc = sqlite3LockStmtTables(rec->stmt);
3335-
} else if (rc == SQLITE_ERROR && comdb2_get_verify_remote_schemas()) {
3335+
} else if (rc == SQLITE_ERROR && comdb2_get_verify_remote_schemas(clnt)) {
33363336
sqlite3ResetFdbSchemas(thd->sqldb);
33373337
return SQLITE_SCHEMA_REMOTE;
33383338
}

0 commit comments

Comments
 (0)