030283b12881d07a2cf7c84b2af320dd9c39b30a braney Sat Feb 28 13:21:59 2026 -0800 fix problem that cause crash if the trackDb cache was turned on and one of the tables in the hg.conf trackDb setting doesn't exist. No RM. Reported by Hillier. diff --git src/hg/lib/jksql.c src/hg/lib/jksql.c index 29f73235774..86f2f2a3a37 100644 --- src/hg/lib/jksql.c +++ src/hg/lib/jksql.c @@ -3237,31 +3237,31 @@ for (ix=0; ;++ix) { name = sqlFieldName(sr); if (name == NULL) errAbort("Can't find Update_time field in show table status result"); if (sameString("Update_time", name)) { updateFieldIndex = ix; break; } } } return updateFieldIndex; } -char *sqlTableUpdate(struct sqlConnection *conn, char *table) +char *sqlTableUpdateMaybeAbort(struct sqlConnection *conn, char *table, boolean shouldAbort) /* Get last update time for table as an SQL string * Note: does NOT work on innoDB! */ { char query[512], **row; struct sqlResult *sr; int updateIx; char *ret; // "show table status" does not support db.table names, so temporarily change database // if table is really db.table. char *connDb = cloneString(sqlGetDatabase(conn)); char tableDb[1024]; char tableName[1024]; sqlParseDbDotTable(connDb, table, tableDb, sizeof tableDb, tableName, sizeof tableName); boolean changeDb = differentStringNullOk(connDb, tableDb); sqlSafef(query, sizeof(query), "show table status like '%s'", tableName); @@ -3274,54 +3274,81 @@ sqlConnectIfUnconnected(conn->failoverConn, TRUE); monitorPrintInfo(conn->failoverConn, "SQL_TABLE_STATUS_FAILOVER"); if (changeDb) sqlConnChangeDb(conn->failoverConn, tableDb, TRUE); sr = sqlGetResult(conn->failoverConn, query); } else { if (changeDb) sqlConnChangeDb(conn, tableDb, TRUE); sr = sqlGetResult(conn, query); } updateIx = getUpdateFieldIndex(sr); row = sqlNextRow(sr); if (row == NULL) + { + if (shouldAbort) errAbort("Database table %s doesn't exist", table); + + ret = NULL; + } +else ret = cloneString(row[updateIx]); sqlFreeResult(&sr); if (changeDb) { if (useFailOver) sqlConnChangeDb(conn->failoverConn, connDb, TRUE); else sqlConnChangeDb(conn, connDb, TRUE); } freeMem(connDb); return ret; } +char *sqlTableUpdate(struct sqlConnection *conn, char *table) +/* Get last update time for table as an SQL string + * Note: does NOT work on innoDB! */ +{ +return sqlTableUpdateMaybeAbort(conn, table, TRUE); +} + time_t sqlTableUpdateTime(struct sqlConnection *conn, char *table) -/* Get last update time for table. +/* Get last update time for table. ErrAbort if table not present * Note: does NOT work on innoDB! */ { char *date = sqlTableUpdate(conn, table); time_t time = sqlDateToUnixTime(date); freeMem(date); return time; } +time_t sqlTableMaybeUpdateTime(struct sqlConnection *conn, char *table) +/* Get last update time for table. Return 0 if table doesn't exist + * Note: does NOT work on innoDB! */ +{ +char *date = sqlTableUpdateMaybeAbort(conn, table, FALSE); + +if (date == NULL) + return 0; + +time_t time = sqlDateToUnixTime(date); +freeMem(date); +return time; +} + static char *sqlTablePropertyFromSchema(struct sqlConnection *conn, char *db, char *table, char *field) /* Get table property. Table must exist or will abort. */ { char query[512], **row; struct sqlResult *sr; char *ret; char tableDb[1024]; char tableName[1024]; sqlParseDbDotTable(db, table, tableDb, sizeof tableDb, tableName, sizeof tableName); sqlSafef(query, sizeof(query), "SELECT %s FROM information_schema.TABLES" " WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'", field, tableDb, tableName); // the failover strategy for failoverConn does not work for this command, // as it never returns an error. So we run this on the failover server // if we have a failover connection and the table is not on the main server