diff --git a/CHANGELOG.md b/CHANGELOG.md
index 124146c4..16502d04 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@
- PostgreSQL: Quote edit value with interval operator
- PostgreSQL: Fix calling functions with name-less parameters
- PostgreSQL: Fix calling functions returing table
+- PostgreSQL: Don't treat user types containing 'file' as blobs (bug #1118)
- PostgreSQL 11-: Avoid duplicate oid in table status (bug #1089)
- Elasticsearch: Support dropping aliases
- Plugins: Methods afterConnect(), processList() and killProcess()
diff --git a/adminer/include/adminer.inc.php b/adminer/include/adminer.inc.php
index ccc68654..316720ce 100644
--- a/adminer/include/adminer.inc.php
+++ b/adminer/include/adminer.inc.php
@@ -304,7 +304,7 @@ class Adminer {
: (preg_match('~json~', $field["type"]) ? "$val"
: $val)
));
- if (preg_match('~blob|bytea|raw|file~', $field["type"]) && !is_utf8($val)) {
+ if (is_blob($field) && !is_utf8($val)) {
$return = "" . lang('%d byte(s)', strlen($original)) . "";
}
return ($link ? "$return" : $return);
@@ -703,7 +703,7 @@ class Adminer {
}
}
}
- if ($key && $functions && !preg_match('~set|blob|bytea|raw|file|bool~', $field["type"])) {
+ if ($key && $functions && !preg_match('~set|bool~', $field["type"]) && !is_blob($field)) {
$return .= "/SQL";
}
}
@@ -843,7 +843,7 @@ class Adminer {
}
}
}
- $result = connection()->query($query, 1); // 1 - MYSQLI_USE_RESULT //! enum and set as numbers
+ $result = connection()->query($query, 1); // 1 - MYSQLI_USE_RESULT
if ($result) {
$insert = "";
$buffer = "";
diff --git a/adminer/include/functions.inc.php b/adminer/include/functions.inc.php
index 2f75bcb5..ef61073e 100644
--- a/adminer/include/functions.inc.php
+++ b/adminer/include/functions.inc.php
@@ -791,6 +791,13 @@ function select_value($val, string $link, array $field, ?string $text_length): s
return adminer()->selectVal($return, $link, $field, $val);
}
+/** Check whether the field type is blob or equivalent
+* @param Field $field
+*/
+function is_blob(array $field): bool {
+ return preg_match('~blob|bytea|raw|file~', $field["type"]) && !in_array($field["type"], idx(driver()->structuredTypes(), lang('User types'), array()));
+}
+
/** Check whether the string is e-mail address */
function is_mail(?string $email): bool {
$atom = '[-a-z0-9!#$%&\'*+/=?^_`{|}~]'; // characters of local-name
diff --git a/adminer/include/html.inc.php b/adminer/include/html.inc.php
index 575682cc..e0f13af8 100644
--- a/adminer/include/html.inc.php
+++ b/adminer/include/html.inc.php
@@ -240,7 +240,7 @@ function input(array $field, $value, ?string $function, ?bool $autofocus = false
$checked = in_array($val, explode(",", $value), true);
echo " ';
}
- } elseif (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
+ } elseif (is_blob($field) && ini_bool("file_uploads")) {
echo "";
} elseif ($function == "json" || preg_match('~^jsonb?$~', $field["type"])) {
echo "';
@@ -324,7 +324,7 @@ function process_input(array $field) {
}
return $value;
}
- if (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
+ if (is_blob($field) && ini_bool("file_uploads")) {
$file = get_file("fields-$idf");
if (!is_string($file)) {
return false; //! report errors
diff --git a/adminer/select.inc.php b/adminer/select.inc.php
index e5ab664a..572a0750 100644
--- a/adminer/select.inc.php
+++ b/adminer/select.inc.php
@@ -423,7 +423,7 @@ if (!$columns && support("table")) {
}
$link = "";
- if (preg_match('~blob|bytea|raw|file~', $field["type"]) && $val != "") {
+ if (is_blob($field) && $val != "") {
$link = ME . 'download=' . urlencode($TABLE) . '&field=' . urlencode($key) . $unique_idf;
}
if (!$link && $val !== null) { // link related items
diff --git a/editor/include/adminer.inc.php b/editor/include/adminer.inc.php
index d54c524d..16c50cc4 100644
--- a/editor/include/adminer.inc.php
+++ b/editor/include/adminer.inc.php
@@ -219,7 +219,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row
function selectVal($val, $link, $field, $original) {
$return = $val;
$link = h($link);
- if (preg_match('~blob|bytea~', $field["type"]) && !is_utf8($val)) {
+ if (is_blob($field) && !is_utf8($val)) {
$return = lang('%d byte(s)', strlen($original));
if (preg_match("~^(GIF|\xFF\xD8\xFF|\x89PNG\x0D\x0A\x1A\x0A)~", $original)) { // GIF|JPG|PNG, getimagetype() works with filename
$return = "
";