public boolean executeDynamicPartitionForTable(Long dbId, Long tableId) {
        Database db = GlobalStateMgr.getCurrentState().getDb(dbId);
        if (db == null) {
            LOG.warn("Automatically removes the schedule because database does not exist, dbId: {}", dbId);
            return true;
        }

        ArrayList<AddPartitionClause> addPartitionClauses = new ArrayList<>();
        ArrayList<DropPartitionClause> dropPartitionClauses;
        String tableName;
        boolean skipAddPartition = false;
        OlapTable olapTable;
        olapTable = (OlapTable) db.getTable(tableId);
        if (olapTable == null) {
            LOG.warn("Automatically removes the schedule because table does not exist, " +
                        "tableId: {}", tableId);
            return true;
        }
        // Only OlapTable has DynamicPartitionProperty
        try (AutoCloseableLock ignore =
                    new AutoCloseableLock(new Locker(), db, Lists.newArrayList(olapTable.getId()), LockType.READ)) {
            if (!olapTable.dynamicPartitionExists()) {
                LOG.warn("Automatically removes the schedule because " +
                            "table[{}] does not have dynamic partition", olapTable.getName());
                return true;
            }
            if (!olapTable.getTableProperty().getDynamicPartitionProperty().isEnabled()) {
                LOG.warn("Automatically removes the schedule because table[{}] " +
                            "does not enable dynamic partition", olapTable.getName());
                return true;
            }

            if (olapTable.getState() != OlapTable.OlapTableState.NORMAL) {
                String errorMsg = "Table[" + olapTable.getName() + "]'s state is not NORMAL." +
                            "Do not allow doing dynamic add partition. table state=" + olapTable.getState();
                recordCreatePartitionFailedMsg(db.getOriginName(), olapTable.getName(), errorMsg);
                skipAddPartition = true;
            }

            // Determine the partition column type
            // if column type is Date, format partition name as yyyyMMdd
            // if column type is DateTime, format partition name as yyyyMMddHHssmm
            // scheduler time should be record even no partition added
            createOrUpdateRuntimeInfo(olapTable.getName(), LAST_SCHEDULER_TIME, TimeUtils.getCurrentFormatTime());
            RangePartitionInfo rangePartitionInfo = (RangePartitionInfo) olapTable.getPartitionInfo();
            if (rangePartitionInfo.getPartitionColumnsSize() != 1) {
                // currently only support partition with single column.
                LOG.warn("Automatically removes the schedule because " +
                            "table[{}] has more than one partition column", olapTable.getName());
                return true;
            }

            try {
                Column partitionColumn = rangePartitionInfo.getPartitionColumns(olapTable.getIdToColumn()).get(0);
                String partitionFormat = DynamicPartitionUtil.getPartitionFormat(partitionColumn);
                if (!skipAddPartition) {
                    addPartitionClauses = getAddPartitionClause(db, olapTable, partitionColumn, partitionFormat);
                }
                dropPartitionClauses = getDropPartitionClause(db, olapTable, partitionColumn, partitionFormat);
                tableName = olapTable.getName();
            } catch (Exception e) {
                LOG.warn("create or drop partition failed", e);
                recordCreatePartitionFailedMsg(db.getOriginName(), olapTable.getName(), e.getMessage());
                return false;
            }
        }

        WarehouseManager warehouseManager = GlobalStateMgr.getCurrentState().getWarehouseMgr();
        ConnectContext ctx = Util.getOrCreateConnectContext();
        ctx.setCurrentWarehouse(warehouseManager.getBackgroundWarehouse().getName());

        Locker locker = new Locker();
        for (DropPartitionClause dropPartitionClause : dropPartitionClauses) {
            if (!locker.lockDatabaseAndCheckExist(db, LockType.WRITE)) {
                LOG.warn("db: {}({}) has been dropped, skip", db.getFullName(), db.getId());
                return false;
            }
            try {
                AlterTableClauseAnalyzer analyzer = new AlterTableClauseAnalyzer(olapTable);
                analyzer.analyze(ctx, dropPartitionClause);

                GlobalStateMgr.getCurrentState().getLocalMetastore().dropPartition(db, olapTable, dropPartitionClause);
                clearDropPartitionFailedMsg(tableName);
            } catch (DdlException e) {
                recordDropPartitionFailedMsg(db.getOriginName(), tableName, e.getMessage());
            } finally {
                locker.unLockDatabase(db, LockType.WRITE);
            }
        }

        if (!skipAddPartition) {
            for (AddPartitionClause addPartitionClause : addPartitionClauses) {
                try {
                    AlterTableClauseAnalyzer alterTableClauseVisitor = new AlterTableClauseAnalyzer(olapTable);
                    alterTableClauseVisitor.analyze(ctx, addPartitionClause);

                    GlobalStateMgr.getCurrentState().getLocalMetastore().addPartitions(ctx,
                                db, tableName, addPartitionClause);
                    clearCreatePartitionFailedMsg(tableName);
                } catch (DdlException e) {
                    recordCreatePartitionFailedMsg(db.getOriginName(), tableName, e.getMessage());
                }
            }
        }
        return false;
    }
@Test
    public void testPartitionColumnDateUseDynamicHour() throws Exception {
        new MockUp<LocalDateTime>() {
            @Mock
            public LocalDateTime now() {
                return  LocalDateTime.of(2023, 3, 30, 1, 1, 1);
            }
        };

        starRocksAssert.withDatabase("test").useDatabase("test")
                .withTable("CREATE TABLE `test_hour_partition2` (\n" +
                        "  `event_day` date NULL COMMENT \"\",\n" +
                        "  `site_id` int(11) NULL DEFAULT \"10\" COMMENT \"\",\n" +
                        "  `city_code` varchar(100) NULL COMMENT \"\",\n" +
                        "  `user_name` varchar(32) NULL DEFAULT \"\" COMMENT \"\",\n" +
                        "  `pv` bigint(20) NULL DEFAULT \"0\" COMMENT \"\"\n" +
                        ") ENGINE=OLAP \n" +
                        "DUPLICATE KEY(`event_day`, `site_id`, `city_code`, `user_name`)\n" +
                        "PARTITION BY RANGE(`event_day`)\n" +
                        "()\n" +
                        "DISTRIBUTED BY HASH(`event_day`, `site_id`) BUCKETS 32 \n" +
                        "PROPERTIES (\n" +
                        "\"replication_num\" = \"1\",\n" +
                        "\"dynamic_partition.enable\" = \"true\",\n" +
                        "\"dynamic_partition.time_unit\" = \"DAY\",\n" +
                        "\"dynamic_partition.time_zone\" = \"Asia/Shanghai\",\n" +
                        "\"dynamic_partition.start\" = \"-1\",\n" +
                        "\"dynamic_partition.end\" = \"10\",\n" +
                        "\"dynamic_partition.prefix\" = \"p\",\n" +
                        "\"dynamic_partition.buckets\" = \"3\",\n" +
                        "\"dynamic_partition.history_partition_num\" = \"0\",\n" +
                        "\"in_memory\" = \"false\",\n" +
                        "\"storage_format\" = \"DEFAULT\",\n" +
                        "\"enable_persistent_index\" = \"false\",\n" +
                        "\"compression\" = \"LZ4\"\n" +
                        ");");

        DynamicPartitionScheduler dynamicPartitionScheduler = GlobalStateMgr.getCurrentState()
                .getDynamicPartitionScheduler();
        Database db = GlobalStateMgr.getCurrentState().getDb("test");
        OlapTable tbl = (OlapTable) db.getTable("test_hour_partition2");
        DynamicPartitionProperty dynamicPartitionProperty = tbl.getTableProperty().getDynamicPartitionProperty();
        dynamicPartitionProperty.setTimeUnit("HOUR");
        boolean result = dynamicPartitionScheduler.executeDynamicPartitionForTable(db.getId(), tbl.getId());
        Assert.assertFalse(result);
    }