@@ -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 */
684685static 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)
865866static 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/**
0 commit comments