<?php
-$PROCEDURE = $_GET["call"];
+$PROCEDURE = ($_GET["name"] ? $_GET["name"] : $_GET["call"]);
page_header(lang('Call') . ": " . h($PROCEDURE), $error);
-$routine = routine($PROCEDURE, (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE"));
+$routine = routine($_GET["call"], (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE"));
$in = array();
$out = array();
foreach ($routine["fields"] as $i => $field) {
echo '<thead><tr><th>' . lang('Name') . '<td>' . lang('Type') . '<td>' . lang('Return type') . "<td> </thead>\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 '<tr' . odd() . '>';
- echo '<th><a href="' . h(ME) . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'callf=' : 'call=') . urlencode($row["ROUTINE_NAME"]) . '">' . h($row["ROUTINE_NAME"]) . '</a>';
+ echo '<th><a href="' . h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'callf=' : 'call=') . urlencode($row["SPECIFIC_NAME"]) . $name) . '">' . h($row["ROUTINE_NAME"]) . '</a>';
echo '<td>' . h($row["ROUTINE_TYPE"]);
echo '<td>' . h($row["DTD_IDENTIFIER"]);
- echo '<td><a href="' . h(ME) . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'function=' : 'procedure=') . urlencode($row["ROUTINE_NAME"]) . '">' . lang('Alter') . "</a>";
+ echo '<td><a href="' . h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'function=' : 'procedure=') . urlencode($row["SPECIFIC_NAME"]) . $name) . '">' . lang('Alter') . "</a>";
}
echo "</table>\n";
}
}
/** 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
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
*/
);
}
- /*
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() {
}
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) {
* @return string
*/
function create_routine($routine, $row) {
- global $inout;
+ global $inout, $jush;
$set = array();
$fields = (array) $row["fields"];
ksort($fields); // enforce fields order
$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;")
;
}
<?php
-$PROCEDURE = $_GET["procedure"];
+$PROCEDURE = ($_GET["name"] ? $_GET["name"] : $_GET["procedure"]);
$routine = (isset($_GET["function"]) ? "FUNCTION" : "PROCEDURE");
$row = $_POST;
$row["fields"] = (array) $row["fields"];
if ($_POST && !process_fields($row["fields"]) && !$error) {
+ $orig = routine($_GET["procedure"], $routine);
$temp_name = "$row[name]_adminer_" . uniqid();
drop_create(
- "DROP $routine " . idf_escape($PROCEDURE),
+ "DROP $routine " . routine_id($PROCEDURE, $orig),
create_routine($routine, $row),
- "DROP $routine " . idf_escape($row["name"]),
+ "DROP $routine " . routine_id($row["name"], $row),
create_routine($routine, array("name" => $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.'),
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;
}
<form action="" method="post" id="form">
<p><?php echo lang('Name'); ?>: <input name="name" value="<?php echo h($row["name"]); ?>" maxlength="64" autocapitalize="off">
-<?php echo ($routine_languages ? lang('Language') . ": " . html_select("language", $routine_languages, $row["language"]) : ""); ?>
+<?php echo ($routine_languages ? lang('Language') . ": " . html_select("language", $routine_languages, $row["language"]) . "\n" : ""); ?>
<input type="submit" value="<?php echo lang('Save'); ?>">
<table cellspacing="0" class="nowrap">
<?php
Fix counting selected rows after going back to select page
PHP <5.3 compatibility even with Elasticsearch enabled
MariaDB: Support JSON since MariaDB 10.2
+PostgreSQL: Support functions
SimpleDB: Document that allow_url_fopen is required
Malay translation