@@ -848,49 +848,70 @@ private ShowResultSet showCreateInternalCatalogTable(ShowCreateTableStmt showStm
848848 Database db = GlobalStateMgr .getCurrentState ().getLocalMetastore ().getDb (showStmt .getDb ());
849849 MetaUtils .checkDbNullAndReport (db , showStmt .getDb ());
850850 List <List <String >> rows = Lists .newArrayList ();
851- Locker locker = new Locker ();
852- locker .lockDatabase (db .getId (), LockType .READ );
853- try {
854- TableName tableName = new TableName (showStmt .getCatalogName (), showStmt .getDb (), showStmt .getTable ());
855- Table table = MetaUtils .getSessionAwareTable (connectContext , db , tableName );
856- if (table == null ) {
857- if (showStmt .getType () != ShowCreateTableStmt .CreateTableType .MATERIALIZED_VIEW ) {
858- ErrorReport .reportSemanticException (ErrorCode .ERR_BAD_TABLE_ERROR , showStmt .getTable ());
859- } else {
860- // For Sync Materialized View, it is a mv index inside OLAP table,
861- // so we can not get it from database.
862- for (Table tbl : GlobalStateMgr .getCurrentState ().getLocalMetastore ().getTables (db .getId ())) {
863- if (tbl .getType () == Table .TableType .OLAP ) {
864- OlapTable olapTable = (OlapTable ) tbl ;
865- List <MaterializedIndexMeta > visibleMaterializedViews =
866- olapTable .getVisibleIndexMetas ();
867- for (MaterializedIndexMeta mvMeta : visibleMaterializedViews ) {
868- if (olapTable .getIndexNameByMetaId (mvMeta .getIndexMetaId ()).equals (showStmt .getTable ())) {
869- if (mvMeta .getOriginStmt () == null ) {
870- String mvName = olapTable .getIndexNameByMetaId (mvMeta .getIndexMetaId ());
871- rows .add (Lists .newArrayList (showStmt .getTable (),
872- ShowMaterializedViewStatus .buildCreateMVSql (olapTable ,
873- mvName , mvMeta ), "utf8" , "utf8_general_ci" ));
874- } else {
875- rows .add (Lists .newArrayList (showStmt .getTable (), mvMeta .getOriginStmt (),
876- "utf8" , "utf8_general_ci" ));
877- }
878-
879- ShowResultSetMetaData showResultSetMetaData = ShowResultSetMetaData .builder ()
880- .addColumn (new Column ("Materialized View" ,
881- TypeFactory .createVarcharType (20 )))
882- .addColumn (new Column ("Create Materialized View" ,
883- TypeFactory .createVarcharType (30 )))
884- .build ();
885- return new ShowResultSet (showResultSetMetaData , rows );
851+ TableName tableName = new TableName (showStmt .getCatalogName (), showStmt .getDb (), showStmt .getTable ());
852+ // Lookup is ConcurrentHashMap-backed (Database.nameToTable) for internal catalog and
853+ // throws SemanticException if the table is missing, so it is safe outside the lock.
854+ Table table = MetaUtils .getSessionAwareTable (connectContext , db , tableName );
855+ // TODO(sync-mv): the (table == null) branch below is currently unreachable -
856+ // MetaUtils.getSessionAwareTable throws SemanticException on miss rather than
857+ // returning null (since #43162, "temporary table part-1"), so the sync-MV
858+ // fallback never runs. As a side effect, SHOW CREATE MATERIALIZED VIEW <sync_mv>
859+ // has been broken since that change (sync MVs live as MaterializedIndexMeta
860+ // inside an OLAP table, not as separately-registered Tables, so they are missed
861+ // by the throwing lookup above). The fallback is kept here as a marker until a
862+ // follow-up commit reworks the lookup to make this path reachable. When that
863+ // happens, the iteration must run under DB READ (or per-table READ) - it reads
864+ // HashMap-backed OlapTable index metadata which is mutated by concurrent
865+ // ALTER/rollup. Today the unlocked iteration is harmless because it never
866+ // executes.
867+ if (table == null ) {
868+ if (showStmt .getType () != ShowCreateTableStmt .CreateTableType .MATERIALIZED_VIEW ) {
869+ ErrorReport .reportSemanticException (ErrorCode .ERR_BAD_TABLE_ERROR , showStmt .getTable ());
870+ } else {
871+ // For Sync Materialized View, it is a mv index inside OLAP table,
872+ // so we can not get it from database.
873+ for (Table tbl : GlobalStateMgr .getCurrentState ().getLocalMetastore ().getTables (db .getId ())) {
874+ if (tbl .getType () == Table .TableType .OLAP ) {
875+ OlapTable olapTable = (OlapTable ) tbl ;
876+ List <MaterializedIndexMeta > visibleMaterializedViews =
877+ olapTable .getVisibleIndexMetas ();
878+ for (MaterializedIndexMeta mvMeta : visibleMaterializedViews ) {
879+ if (olapTable .getIndexNameByMetaId (mvMeta .getIndexMetaId ()).equals (showStmt .getTable ())) {
880+ if (mvMeta .getOriginStmt () == null ) {
881+ String mvName = olapTable .getIndexNameByMetaId (mvMeta .getIndexMetaId ());
882+ rows .add (Lists .newArrayList (showStmt .getTable (),
883+ ShowMaterializedViewStatus .buildCreateMVSql (olapTable ,
884+ mvName , mvMeta ), "utf8" , "utf8_general_ci" ));
885+ } else {
886+ rows .add (Lists .newArrayList (showStmt .getTable (), mvMeta .getOriginStmt (),
887+ "utf8" , "utf8_general_ci" ));
886888 }
889+
890+ ShowResultSetMetaData showResultSetMetaData = ShowResultSetMetaData .builder ()
891+ .addColumn (new Column ("Materialized View" ,
892+ TypeFactory .createVarcharType (20 )))
893+ .addColumn (new Column ("Create Materialized View" ,
894+ TypeFactory .createVarcharType (30 )))
895+ .build ();
896+ return new ShowResultSet (showResultSetMetaData , rows );
887897 }
888898 }
889899 }
890- ErrorReport .reportSemanticException (ErrorCode .ERR_BAD_TABLE_ERROR , showStmt .getTable ());
891900 }
901+ ErrorReport .reportSemanticException (ErrorCode .ERR_BAD_TABLE_ERROR , showStmt .getTable ());
902+ }
903+ }
904+ Locker locker = new Locker ();
905+ locker .lockTableWithIntensiveDbLock (db .getId (), table .getId (), LockType .READ );
906+ try {
907+ // Revalidate by name to detect concurrent DROP/RENAME between unlocked lookup
908+ // and lock acquisition. The table id is stable for a given Table object, so an
909+ // id-based check would miss a RENAME that re-binds the name to a different
910+ // (or no) table; revalidate via the same lookup path so both regular and
911+ // temporary tables are handled correctly.
912+ if (MetaUtils .getSessionAwareTable (connectContext , db , tableName ) != table ) {
913+ ErrorReport .reportSemanticException (ErrorCode .ERR_BAD_TABLE_ERROR , showStmt .getTable ());
892914 }
893-
894915 List <String > createTableStmt = Lists .newArrayList ();
895916 AstToStringBuilder .getDdlStmt (table , createTableStmt , null , null , false , true /* hide password */ );
896917 if (createTableStmt .isEmpty ()) {
@@ -943,7 +964,7 @@ private ShowResultSet showCreateInternalCatalogTable(ShowCreateTableStmt showStm
943964 return new ShowResultSet (showResultMetaFactory .getMetadata (showStmt ), rows );
944965 }
945966 } finally {
946- locker .unLockDatabase (db .getId (), LockType .READ );
967+ locker .unLockTableWithIntensiveDbLock (db . getId (), table .getId (), LockType .READ );
947968 }
948969 }
949970
@@ -1882,7 +1903,7 @@ public ShowResultSet visitShowTabletStatement(ShowTabletStmt statement, ConnectC
18821903 dbName = db .getFullName ();
18831904
18841905 Locker locker = new Locker ();
1885- locker .lockDatabase (db .getId (), LockType .READ );
1906+ locker .lockTableWithIntensiveDbLock (db .getId (), tableId , LockType .READ );
18861907 try {
18871908 Table table = GlobalStateMgr .getCurrentState ().getLocalMetastore ().getTable (db .getId (), tableId );
18881909 if (!(table instanceof OlapTable )) {
@@ -1943,7 +1964,7 @@ public ShowResultSet visitShowTabletStatement(ShowTabletStmt statement, ConnectC
19431964 }
19441965
19451966 } finally {
1946- locker .unLockDatabase (db .getId (), LockType .READ );
1967+ locker .unLockTableWithIntensiveDbLock (db .getId (), tableId , LockType .READ );
19471968 }
19481969 } while (false );
19491970
@@ -1962,19 +1983,25 @@ public ShowResultSet visitShowTabletStatement(ShowTabletStmt statement, ConnectC
19621983 Database db = globalStateMgr .getLocalMetastore ().getDb (dbName );
19631984 MetaUtils .checkDbNullAndReport (db , dbName );
19641985
1986+ // Lookup is ConcurrentHashMap-backed for the internal catalog and throws on missing
1987+ // table, so it is safe outside the lock.
1988+ TableName tableName = new TableName (tableRef .getCatalogName (), tableRef .getDbName (),
1989+ tableRef .getTableName ());
1990+ Table table = MetaUtils .getSessionAwareTable (context , db , tableName );
1991+ if (!table .isNativeTableOrMaterializedView ()) {
1992+ ErrorReport .reportSemanticException (ErrorCode .ERR_NOT_OLAP_TABLE , statement .getTableName ());
1993+ }
1994+
19651995 Locker locker = new Locker ();
1966- locker .lockDatabase (db .getId (), LockType .READ );
1996+ locker .lockTableWithIntensiveDbLock (db . getId (), table .getId (), LockType .READ );
19671997 try {
1968- Table table = MetaUtils .getSessionAwareTable (
1969- context , db , new TableName (tableRef .getCatalogName (), tableRef .getDbName (),
1970- tableRef .getTableName ()));
1971- if (table == null ) {
1972- ErrorReport .reportSemanticException (ErrorCode .ERR_BAD_TABLE_ERROR , statement .getTableName ());
1973- }
1974- if (!table .isNativeTableOrMaterializedView ()) {
1975- ErrorReport .reportSemanticException (ErrorCode .ERR_NOT_OLAP_TABLE , statement .getTableName ());
1998+ // Revalidate by name to detect concurrent DROP/RENAME between unlocked lookup
1999+ // and lock acquisition. Id-based check would miss a RENAME that re-binds the
2000+ // name to a different table; re-running the same lookup catches that.
2001+ if (MetaUtils .getSessionAwareTable (context , db , tableName ) != table ) {
2002+ ErrorReport .reportSemanticException (ErrorCode .ERR_BAD_TABLE_ERROR ,
2003+ statement .getTableName ());
19762004 }
1977-
19782005 Pair <Boolean , Boolean > privResult = Authorizer .checkPrivForShowTablet (
19792006 context , db .getFullName (), table );
19802007 if (!privResult .first ) {
@@ -2068,7 +2095,7 @@ context, db, new TableName(tableRef.getCatalogName(), tableRef.getDbName(),
20682095 rows .add (oneTablet );
20692096 }
20702097 } finally {
2071- locker .unLockDatabase (db .getId (), LockType .READ );
2098+ locker .unLockTableWithIntensiveDbLock (db . getId (), table .getId (), LockType .READ );
20722099 }
20732100 }
20742101
0 commit comments