PostgreSQL: Don't treat interval type as number (bug #474)

This commit is contained in:
Jakub Vrana 2018-02-06 12:17:01 +01:00
parent 11a7fc0277
commit 6cfb3676a7
8 changed files with 20 additions and 10 deletions

View file

@ -1071,7 +1071,7 @@ if (!defined("DRIVER")) {
"binary" => "md5/sha1",
"date|time" => "now",
), array(
"(^|[^o])int|float|double|decimal" => "+/-", // not point
number_type() => "+/-",
"date" => "+ interval/- interval",
"time" => "addtime/subtime",
"char|text" => "concat",

View file

@ -789,7 +789,7 @@ AND typelem = 0"
"char" => "md5",
"date|time" => "now",
), array(
"int|numeric|real|money" => "+/-",
number_type() => "+/-",
"date|time" => "+ interval/- interval", //! escape
"char|text" => "||",
)

View file

@ -543,7 +543,7 @@ class Adminer {
$cols = array();
foreach ($fields as $name => $field) {
$is_text = preg_match('~char|text|enum|set~', $field["type"]);
if ((is_numeric($val["val"]) || !preg_match('~(^|[^o])int|float|double|decimal|bit~', $field["type"]))
if ((is_numeric($val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"]))
&& (!preg_match("~[\x80-\xFF]~", $val["val"]) || $is_text)
) {
$name = idf_escape($name);
@ -828,7 +828,7 @@ class Adminer {
foreach ($row as $key => $val) {
$field = $fields[$key];
$row[$key] = ($val !== null
? unconvert_field($field, preg_match('~(^|[^o])int|float|double|decimal~', $field["type"]) && $val != '' ? $val : q($val))
? unconvert_field($field, preg_match('~' . number_type() . '~', $field["type"]) && $val != '' ? $val : q($val))
: "NULL"
);
}

View file

@ -155,7 +155,7 @@ echo optionlist(array_merge($extra_types, $structured_types), $type);
<?php echo script("mixin(qsl('select'), {onfocus: function () { lastType = selectValue(this); }, onchange: editingTypeChange});", ""); ?>
<td><input name="<?php echo h($key); ?>[length]" value="<?php echo h($field["length"]); ?>" size="3"<?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); ?> aria-labelledby="label-length"><?php echo script("mixin(qsl('input'), {onfocus: editingLengthFocus, oninput: editingLengthChange});", ""); ?><td class="options"><?php //! type="number" with enabled JavaScript
echo "<select name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>';
echo ($unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match('~((^|[^o])int|float|double|decimal)$~', $type) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
echo ($unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match('~' . number_type() . '~', $type) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>' . optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), $field["on_update"]) . '</select>' : '');
echo ($foreign_keys ? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $on_actions), $field["on_delete"]) . "</select> " : " "); // space for IE
}
@ -181,7 +181,7 @@ function process_type($field, $collate = "COLLATE") {
global $unsigned;
return " $field[type]"
. process_length($field["length"])
. (preg_match('~(^|[^o])int|float|double|decimal~', $field["type"]) && in_array($field["unsigned"], $unsigned) ? " $field[unsigned]" : "")
. (preg_match('~' . number_type() . '~', $field["type"]) && in_array($field["unsigned"], $unsigned) ? " $field[unsigned]" : "")
. (preg_match('~char|text|enum|set~', $field["type"]) && $field["collation"] ? " $collate " . q($field["collation"]) : "")
;
}

View file

@ -41,6 +41,13 @@ function number($val) {
return preg_replace('~[^0-9]+~', '', $val);
}
/** Get regular expression to match numeric types
* @return string
*/
function number_type() {
return '(?<!o)int(?!er)|numeric|real|float|double|decimal|money'; // not point, not interval
}
/** Disable magic_quotes_gpc
* @param array e.g. (&$_GET, &$_POST, &$_COOKIE)
* @param bool whether to leave values as is
@ -970,7 +977,7 @@ function input($field, $value, $function) {
}
// type='date' and type='time' display localized value which may be confusing, type='datetime' uses 'T' as date and time separator
echo "<input"
. ((!$has_function || $function === "") && preg_match('~(?<!o)int~', $field["type"]) && !preg_match('~\[\]~', $field["full_type"]) ? " type='number'" : "")
. ((!$has_function || $function === "") && preg_match('~(?<!o)int(?!er)~', $field["type"]) && !preg_match('~\[\]~', $field["full_type"]) ? " type='number'" : "")
. " value='" . h($value) . "'" . ($maxlength ? " data-maxlength='$maxlength'" : "")
. (preg_match('~char|binary~', $field["type"]) && $maxlength > 20 ? " size='40'" : "")
. "$attrs>"

View file

@ -316,7 +316,7 @@ function editingTypeChange() {
alterClass(el, 'hidden', !/(char|text|enum|set)$/.test(text));
}
if (el.name == name + '[unsigned]') {
alterClass(el, 'hidden', !/((^|[^o])int|float|double|decimal)$/.test(text));
alterClass(el, 'hidden', !/(^|[^o])int(?!er)|numeric|real|float|double|decimal|money/.test(text));
}
if (el.name == name + '[on_update]') {
alterClass(el, 'hidden', !/timestamp|datetime/.test(text)); // MySQL supports datetime since 5.6.5

View file

@ -1,3 +1,6 @@
Adminer 4.6.1-dev:
PostgreSQL: Don't treat interval type as number (bug #474)
Adminer 4.6.0 (released 2018-02-05):
Fix counting selected rows after going back to select page
PHP <5.3 compatibility even with Elasticsearch enabled

View file

@ -197,7 +197,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
if ($link) {
$return = "<a href='$link'" . (is_url($link) ? target_blank() : "") . ">$return</a>";
}
if (!$link && !like_bool($field) && preg_match('~int|float|double|decimal~', $field["type"])) {
if (!$link && !like_bool($field) && preg_match('~' . number_type() . '~', $field["type"])) {
$return = "<div class='number'>$return</div>"; // Firefox doesn't support <colgroup>
} elseif (preg_match('~date~', $field["type"])) {
$return = "<div class='datetime'>$return</div>";
@ -342,7 +342,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
if (($key < 0 ? "" : $col) . $val != "") {
$conds = array();
foreach (($col != "" ? array($col => $fields[$col]) : $fields) as $name => $field) {
if ($col != "" || is_numeric($val) || !preg_match('~int|float|double|decimal~', $field["type"])) {
if ($col != "" || is_numeric($val) || !preg_match('~' . number_type() . '~', $field["type"])) {
$name = idf_escape($name);
if ($col != "" && $field["type"] == "enum") {
$conds[] = (in_array(0, $val) ? "$name IS NULL OR " : "") . "$name IN (" . implode(", ", array_map('intval', $val)) . ")";