Repository: dbeaver/dbeaver
Issue: [mysql] incorrect handling of stored procedure and function with the same name

- Operating system (distribution) and version: Debian 10
- DBeaver version: 21.0.2
- Database name and version: mysql 8.0.23
- Driver name: MySQL

If there are one stored procedure and one function with the same name, you could loose function while editing the procedure.

1) create "test" PROCEDURE

```
DELIMITER $$
$$
CREATE PROCEDURE testdb.test()
BEGIN
END$$
DELIMITER ;
```

2) create "test" FUNCTION

```
DELIMITER $$
$$
CREATE FUNCTION testdb.test()
RETURNS INT
DETERMINISTIC
BEGIN
	RETURN 0;
END$$
DELIMITER ;
```

3) open the procedure, edit and save. CTRL+S generates the correct code:

```
DROP PROCEDURE IF EXISTS testdb.test;

DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `testdb`.`test`()
BEGIN
	# test
END$$
DELIMITER ;
```

4) edit the procedure again and press CTRL+S.... boom:

DROP **FUNCTION** IF EXISTS testdb.test;

DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `testdb`.`test`()
BEGIN
	# test 1
END$$
DELIMITER ;

As you can see the second time you save, there is a DROP FUNCTION and CREATE PROCEDURE, so "test" function is deleted. 

Changed files:
plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLCatalog.java
plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLProcedure.java

diff --git a/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLCatalog.java b/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLCatalog.java
index 3b2caa3e88..c6ad2fa070 100644
--- a/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLCatalog.java
+++ b/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLCatalog.java
@@ -923,12 +923,15 @@ public class MySQLCatalog implements
                 "SELECT * FROM " + MySQLConstants.META_TABLE_ROUTINES +
                     "\\nWHERE " + MySQLConstants.COL_ROUTINE_SCHEMA + "=?" +
                     (object == null && objectName == null ? "" : " AND " + MySQLConstants.COL_ROUTINE_NAME + "=?") +
-                    "\\nAND ROUTINE_TYPE IN ('PROCEDURE','FUNCTION')" +
+                    " AND ROUTINE_TYPE" + (object == null ? " IN ('PROCEDURE','FUNCTION')" : "=?") +
                     "\\nORDER BY " + MySQLConstants.COL_ROUTINE_NAME
             );
             dbStat.setString(1, owner.getName());
             if (object != null || objectName != null) {
                 dbStat.setString(2, object != null ? object.getName() : objectName);
+                if (object != null) {
+                    dbStat.setString(3, String.valueOf(object.getProcedureType()));
+                }
             }
             return dbStat;
         }
diff --git a/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLProcedure.java b/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLProcedure.java
index bf1cf13f76..4b98d7f7e3 100644
--- a/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLProcedure.java
+++ b/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLProcedure.java
@@ -20,10 +20,7 @@ import org.jkiss.code.NotNull;
 import org.jkiss.dbeaver.DBException;
 import org.jkiss.dbeaver.Log;
 import org.jkiss.dbeaver.ext.mysql.MySQLConstants;
-import org.jkiss.dbeaver.model.DBPDataKind;
-import org.jkiss.dbeaver.model.DBPEvaluationContext;
-import org.jkiss.dbeaver.model.DBPRefreshableObject;
-import org.jkiss.dbeaver.model.DBUtils;
+import org.jkiss.dbeaver.model.*;
 import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement;
 import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet;
 import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession;
@@ -44,7 +41,7 @@ import java.util.Map;
 /**
  * MySQLProcedure
  */
-public class MySQLProcedure extends AbstractProcedure<MySQLDataSource, MySQLCatalog> implements MySQLSourceObject, DBPRefreshableObject
+public class MySQLProcedure extends AbstractProcedure<MySQLDataSource, MySQLCatalog> implements MySQLSourceObject, DBPRefreshableObject, DBPUniqueObject
 {
     private static final Log log = Log.getLog(MySQLProcedure.class);
 
@@ -263,6 +260,15 @@ public class MySQLProcedure extends AbstractProcedure<MySQLDataSource, MySQLCata
         return getContainer().proceduresCache.refreshObject(monitor, getContainer(), this);
     }
 
+    @NotNull
+    @Override
+    public String getUniqueName() {
+        if (getProcedureType() == DBSProcedureType.PROCEDURE) {
+            return getName() + ' ' + getResultType();
+        }
+        return getName();
+    }
+
     @Override
     public String toString() {
         return procedureType.name() + " " + getName();