diff --git a/adminer/call.inc.php b/adminer/call.inc.php
index cc64027a..9ceb398f 100644
--- a/adminer/call.inc.php
+++ b/adminer/call.inc.php
@@ -1,8 +1,8 @@
$field) {
diff --git a/adminer/db.inc.php b/adminer/db.inc.php
index 671c232f..9439a30b 100644
--- a/adminer/db.inc.php
+++ b/adminer/db.inc.php
@@ -159,11 +159,12 @@ if ($adminer->homepage()) {
echo '' . lang('Name') . ' | ' . lang('Type') . ' | ' . lang('Return type') . " | |
\n";
odd('');
foreach ($routines as $row) {
+ $name = ($row["SPECIFIC_NAME"] == $row["ROUTINE_NAME"] ? "" : "&name=" . urlencode($row["ROUTINE_NAME"])); // not computed on the pages to be able to print the header first
echo '
';
- echo '' . h($row["ROUTINE_NAME"]) . '';
+ echo ' | ' . h($row["ROUTINE_NAME"]) . '';
echo ' | ' . h($row["ROUTINE_TYPE"]);
echo ' | ' . h($row["DTD_IDENTIFIER"]);
- echo ' | ' . lang('Alter') . "";
+ echo ' | ' . lang('Alter') . "";
}
echo "\n";
}
diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php
index 6504536c..5adbac83 100644
--- a/adminer/drivers/mysql.inc.php
+++ b/adminer/drivers/mysql.inc.php
@@ -840,10 +840,10 @@ if (!defined("DRIVER")) {
}
/** Get list of routines
- * @return array ("ROUTINE_TYPE" => , "ROUTINE_NAME" => , "DTD_IDENTIFIER" => )
+ * @return array ("SPECIFIC_NAME" => , "ROUTINE_NAME" => , "ROUTINE_TYPE" => , "DTD_IDENTIFIER" => )
*/
function routines() {
- return get_rows("SELECT ROUTINE_NAME, ROUTINE_TYPE, DTD_IDENTIFIER FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q(DB));
+ return get_rows("SELECT ROUTINE_NAME AS SPECIFIC_NAME, ROUTINE_NAME, ROUTINE_TYPE, DTD_IDENTIFIER FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q(DB));
}
/** Get list of available routine languages
@@ -853,6 +853,15 @@ if (!defined("DRIVER")) {
return array(); // "SQL" not required
}
+ /** Get routine signature
+ * @param string
+ * @param array result of routine()
+ * @return string
+ */
+ function routine_id($name, $row) {
+ return idf_escape($name);
+ }
+
/** Get last auto increment ID
* @return string
*/
diff --git a/adminer/drivers/pgsql.inc.php b/adminer/drivers/pgsql.inc.php
index 793a02ff..cd24826f 100644
--- a/adminer/drivers/pgsql.inc.php
+++ b/adminer/drivers/pgsql.inc.php
@@ -541,30 +541,36 @@ ORDER BY conkey, conname") as $row) {
);
}
- /*
function routine($name, $type) {
- //! there can be more functions with the same name differing only in parameters, it must be also passed to DROP FUNCTION
- //! no procedures, only functions
- //! different syntax of CREATE FUNCTION
- $rows = get_rows('SELECT pg_catalog.format_type(p.prorettype, NULL) AS "returns", p.prosrc AS "definition"
-FROM pg_catalog.pg_namespace n
-JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid
-WHERE n.nspname = current_schema() AND p.proname = ' . q($name));
- $rows[0]["fields"] = array(); //!
- return $rows[0];
+ $rows = get_rows('SELECT routine_definition AS definition, LOWER(external_language) AS language, *
+FROM information_schema.routines
+WHERE routine_schema = current_schema() AND specific_name = ' . q($name));
+ $return = $rows[0];
+ $return["returns"] = array("type" => $return["type_udt_name"]);
+ $return["fields"] = get_rows('SELECT parameter_name AS field, data_type AS type, character_maximum_length AS length, parameter_mode AS inout
+FROM information_schema.parameters
+WHERE specific_schema = current_schema() AND specific_name = ' . q($name) . '
+ORDER BY ordinal_position');
+ return $return;
}
- */
function routines() {
- return get_rows('SELECT p.proname AS "ROUTINE_NAME", p.proargtypes AS "ROUTINE_TYPE", pg_catalog.format_type(p.prorettype, NULL) AS "DTD_IDENTIFIER"
-FROM pg_catalog.pg_namespace n
-JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid
-WHERE n.nspname = current_schema()
-ORDER BY p.proname');
+ return get_rows('SELECT specific_name AS "SPECIFIC_NAME", routine_type AS "ROUTINE_TYPE", routine_name AS "ROUTINE_NAME", type_udt_name AS "DTD_IDENTIFIER"
+FROM information_schema.routines
+WHERE routine_schema = current_schema()
+ORDER BY SPECIFIC_NAME');
}
function routine_languages() {
- return get_vals("SELECT langname FROM pg_catalog.pg_language");
+ return get_vals("SELECT LOWER(lanname) FROM pg_catalog.pg_language");
+ }
+
+ function routine_id($name, $row) {
+ $return = array();
+ foreach ($row["fields"] as $field) {
+ $return[] = $field["type"];
+ }
+ return idf_escape($name) . "(" . implode(", ", $return) . ")";
}
function last_id() {
@@ -727,7 +733,7 @@ AND typelem = 0"
}
function support($feature) {
- return preg_match('~^(database|table|columns|sql|indexes|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|processlist|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature); //! routine|
+ return preg_match('~^(database|table|columns|sql|indexes|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|routine|processlist|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature);
}
function kill_process($val) {
diff --git a/adminer/include/editing.inc.php b/adminer/include/editing.inc.php
index 23a174d0..983e6c0d 100644
--- a/adminer/include/editing.inc.php
+++ b/adminer/include/editing.inc.php
@@ -413,7 +413,7 @@ function create_trigger($on, $row) {
* @return string
*/
function create_routine($routine, $row) {
- global $inout;
+ global $inout, $jush;
$set = array();
$fields = (array) $row["fields"];
ksort($fields); // enforce fields order
@@ -422,13 +422,13 @@ function create_routine($routine, $row) {
$set[] = (preg_match("~^($inout)\$~", $field["inout"]) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET");
}
}
+ $definition = rtrim("\n$row[definition]", ";");
return "CREATE $routine "
. idf_escape(trim($row["name"]))
. " (" . implode(", ", $set) . ")"
. (isset($_GET["function"]) ? " RETURNS" . process_type($row["returns"], "CHARACTER SET") : "")
. ($row["language"] ? " LANGUAGE $row[language]" : "")
- . rtrim("\n$row[definition]", ";")
- . ";"
+ . ($jush == "pgsql" ? " AS " . q($definition) : "$definition;")
;
}
diff --git a/adminer/procedure.inc.php b/adminer/procedure.inc.php
index fede3e33..942dd189 100644
--- a/adminer/procedure.inc.php
+++ b/adminer/procedure.inc.php
@@ -1,17 +1,18 @@
$temp_name) + $row),
- "DROP $routine " . idf_escape($temp_name),
+ "DROP $routine " . routine_id($temp_name, $row),
substr(ME, 0, -1),
lang('Routine has been dropped.'),
lang('Routine has been altered.'),
@@ -24,7 +25,7 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
page_header(($PROCEDURE != "" ? (isset($_GET["function"]) ? lang('Alter function') : lang('Alter procedure')) . ": " . h($PROCEDURE) : (isset($_GET["function"]) ? lang('Create function') : lang('Create procedure'))), $error);
if (!$_POST && $PROCEDURE != "") {
- $row = routine($PROCEDURE, $routine);
+ $row = routine($_GET["procedure"], $routine);
$row["name"] = $PROCEDURE;
}
@@ -35,7 +36,7 @@ $routine_languages = routine_languages();
|