Translated using Weblate (Slovenian)
[phpmyadmin.git] / libraries / classes / Types.php
blobd8f1fd17124ab78bc3beda5f23c4ac94996a6a54
1 <?php
2 /**
3 * SQL data types definition
4 */
6 declare(strict_types=1);
8 namespace PhpMyAdmin;
10 use function array_diff;
11 use function array_merge;
12 use function array_push;
13 use function htmlspecialchars;
14 use function in_array;
15 use function mb_strtoupper;
16 use function sort;
17 use function sprintf;
18 use function strncasecmp;
20 /**
21 * Class holding type definitions for MySQL and MariaDB.
23 class Types
25 /** @var DatabaseInterface Database interface */
26 private $dbi;
28 /**
29 * @param DatabaseInterface $dbi Database interface instance
31 public function __construct($dbi)
33 $this->dbi = $dbi;
36 /**
37 * Returns list of unary operators.
39 * @return string[]
41 public function getUnaryOperators()
43 return [
44 'IS NULL',
45 'IS NOT NULL',
46 "= ''",
47 "!= ''",
51 /**
52 * Check whether operator is unary.
54 * @param string $op operator name
56 * @return bool
58 public function isUnaryOperator($op)
60 return in_array($op, $this->getUnaryOperators());
63 /**
64 * Returns list of operators checking for NULL.
66 * @return string[]
68 public function getNullOperators()
70 return [
71 'IS NULL',
72 'IS NOT NULL',
76 /**
77 * ENUM search operators
79 * @return string[]
81 public function getEnumOperators()
83 return [
84 '=',
85 '!=',
89 /**
90 * TEXT search operators
92 * @return string[]
94 public function getTextOperators()
96 return [
97 'LIKE',
98 'LIKE %...%',
99 'NOT LIKE',
100 'NOT LIKE %...%',
101 '=',
102 '!=',
103 'REGEXP',
104 'REGEXP ^...$',
105 'NOT REGEXP',
106 "= ''",
107 "!= ''",
108 'IN (...)',
109 'NOT IN (...)',
110 'BETWEEN',
111 'NOT BETWEEN',
116 * Number search operators
118 * @return string[]
120 public function getNumberOperators()
122 return [
123 '=',
124 '>',
125 '>=',
126 '<',
127 '<=',
128 '!=',
129 'LIKE',
130 'LIKE %...%',
131 'NOT LIKE',
132 'NOT LIKE %...%',
133 'IN (...)',
134 'NOT IN (...)',
135 'BETWEEN',
136 'NOT BETWEEN',
141 * Returns operators for given type
143 * @param string $type Type of field
144 * @param bool $null Whether field can be NULL
146 * @return string[]
148 public function getTypeOperators($type, $null)
150 $ret = [];
151 $class = $this->getTypeClass($type);
153 if (strncasecmp($type, 'enum', 4) == 0) {
154 $ret = array_merge($ret, $this->getEnumOperators());
155 } elseif ($class === 'CHAR') {
156 $ret = array_merge($ret, $this->getTextOperators());
157 } else {
158 $ret = array_merge($ret, $this->getNumberOperators());
161 if ($null) {
162 $ret = array_merge($ret, $this->getNullOperators());
165 return $ret;
169 * Returns operators for given type as html options
171 * @param string $type Type of field
172 * @param bool $null Whether field can be NULL
173 * @param string $selectedOperator Option to be selected
175 * @return string Generated Html
177 public function getTypeOperatorsHtml($type, $null, $selectedOperator = null)
179 $html = '';
181 foreach ($this->getTypeOperators($type, $null) as $fc) {
182 if (isset($selectedOperator) && $selectedOperator == $fc) {
183 $selected = ' selected="selected"';
184 } else {
185 $selected = '';
188 $html .= '<option value="' . htmlspecialchars($fc) . '"'
189 . $selected . '>'
190 . htmlspecialchars($fc) . '</option>';
193 return $html;
197 * Returns the data type description.
199 * @param string $type The data type to get a description.
201 * @return string
203 public function getTypeDescription($type)
205 $type = mb_strtoupper($type);
206 switch ($type) {
207 case 'TINYINT':
208 return __(
209 'A 1-byte integer, signed range is -128 to 127, unsigned range is ' .
210 '0 to 255'
213 case 'SMALLINT':
214 return __(
215 'A 2-byte integer, signed range is -32,768 to 32,767, unsigned ' .
216 'range is 0 to 65,535'
219 case 'MEDIUMINT':
220 return __(
221 'A 3-byte integer, signed range is -8,388,608 to 8,388,607, ' .
222 'unsigned range is 0 to 16,777,215'
225 case 'INT':
226 return __(
227 'A 4-byte integer, signed range is ' .
228 '-2,147,483,648 to 2,147,483,647, unsigned range is 0 to ' .
229 '4,294,967,295'
232 case 'BIGINT':
233 return __(
234 'An 8-byte integer, signed range is -9,223,372,036,854,775,808 ' .
235 'to 9,223,372,036,854,775,807, unsigned range is 0 to ' .
236 '18,446,744,073,709,551,615'
239 case 'DECIMAL':
240 return __(
241 'A fixed-point number (M, D) - the maximum number of digits (M) ' .
242 'is 65 (default 10), the maximum number of decimals (D) is 30 ' .
243 '(default 0)'
246 case 'FLOAT':
247 return __(
248 'A small floating-point number, allowable values are ' .
249 '-3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to ' .
250 '3.402823466E+38'
253 case 'DOUBLE':
254 return __(
255 'A double-precision floating-point number, allowable values are ' .
256 '-1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and ' .
257 '2.2250738585072014E-308 to 1.7976931348623157E+308'
260 case 'REAL':
261 return __(
262 'Synonym for DOUBLE (exception: in REAL_AS_FLOAT SQL mode it is ' .
263 'a synonym for FLOAT)'
266 case 'BIT':
267 return __(
268 'A bit-field type (M), storing M of bits per value (default is 1, ' .
269 'maximum is 64)'
272 case 'BOOLEAN':
273 return __(
274 'A synonym for TINYINT(1), a value of zero is considered false, ' .
275 'nonzero values are considered true'
278 case 'SERIAL':
279 return __('An alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE');
281 case 'DATE':
282 return sprintf(
283 __('A date, supported range is %1$s to %2$s'),
284 '1000-01-01',
285 '9999-12-31'
288 case 'DATETIME':
289 return sprintf(
290 __('A date and time combination, supported range is %1$s to %2$s'),
291 '1000-01-01 00:00:00',
292 '9999-12-31 23:59:59'
295 case 'TIMESTAMP':
296 return __(
297 'A timestamp, range is 1970-01-01 00:00:01 UTC to 2038-01-09 ' .
298 '03:14:07 UTC, stored as the number of seconds since the epoch ' .
299 '(1970-01-01 00:00:00 UTC)'
302 case 'TIME':
303 return sprintf(
304 __('A time, range is %1$s to %2$s'),
305 '-838:59:59',
306 '838:59:59'
309 case 'YEAR':
310 return __(
311 'A year in four-digit (4, default) or two-digit (2) format, the ' .
312 'allowable values are 70 (1970) to 69 (2069) or 1901 to 2155 and ' .
313 '0000'
316 case 'CHAR':
317 return __(
318 'A fixed-length (0-255, default 1) string that is always ' .
319 'right-padded with spaces to the specified length when stored'
322 case 'VARCHAR':
323 return sprintf(
325 'A variable-length (%s) string, the effective maximum length ' .
326 'is subject to the maximum row size'
328 '0-65,535'
331 case 'TINYTEXT':
332 return __(
333 'A TEXT column with a maximum length of 255 (2^8 - 1) characters, ' .
334 'stored with a one-byte prefix indicating the length of the value ' .
335 'in bytes'
338 case 'TEXT':
339 return __(
340 'A TEXT column with a maximum length of 65,535 (2^16 - 1) ' .
341 'characters, stored with a two-byte prefix indicating the length ' .
342 'of the value in bytes'
345 case 'MEDIUMTEXT':
346 return __(
347 'A TEXT column with a maximum length of 16,777,215 (2^24 - 1) ' .
348 'characters, stored with a three-byte prefix indicating the ' .
349 'length of the value in bytes'
352 case 'LONGTEXT':
353 return __(
354 'A TEXT column with a maximum length of 4,294,967,295 or 4GiB ' .
355 '(2^32 - 1) characters, stored with a four-byte prefix indicating ' .
356 'the length of the value in bytes'
359 case 'BINARY':
360 return __(
361 'Similar to the CHAR type, but stores binary byte strings rather ' .
362 'than non-binary character strings'
365 case 'VARBINARY':
366 return __(
367 'Similar to the VARCHAR type, but stores binary byte strings ' .
368 'rather than non-binary character strings'
371 case 'TINYBLOB':
372 return __(
373 'A BLOB column with a maximum length of 255 (2^8 - 1) bytes, ' .
374 'stored with a one-byte prefix indicating the length of the value'
377 case 'MEDIUMBLOB':
378 return __(
379 'A BLOB column with a maximum length of 16,777,215 (2^24 - 1) ' .
380 'bytes, stored with a three-byte prefix indicating the length of ' .
381 'the value'
384 case 'BLOB':
385 return __(
386 'A BLOB column with a maximum length of 65,535 (2^16 - 1) bytes, ' .
387 'stored with a two-byte prefix indicating the length of the value'
390 case 'LONGBLOB':
391 return __(
392 'A BLOB column with a maximum length of 4,294,967,295 or 4GiB ' .
393 '(2^32 - 1) bytes, stored with a four-byte prefix indicating the ' .
394 'length of the value'
397 case 'ENUM':
398 return __(
399 'An enumeration, chosen from the list of up to 65,535 values or ' .
400 "the special '' error value"
403 case 'SET':
404 return __('A single value chosen from a set of up to 64 members');
406 case 'GEOMETRY':
407 return __('A type that can store a geometry of any type');
409 case 'POINT':
410 return __('A point in 2-dimensional space');
412 case 'LINESTRING':
413 return __('A curve with linear interpolation between points');
415 case 'POLYGON':
416 return __('A polygon');
418 case 'MULTIPOINT':
419 return __('A collection of points');
421 case 'MULTILINESTRING':
422 return __(
423 'A collection of curves with linear interpolation between points'
426 case 'MULTIPOLYGON':
427 return __('A collection of polygons');
429 case 'GEOMETRYCOLLECTION':
430 return __('A collection of geometry objects of any type');
432 case 'JSON':
433 return __(
434 'Stores and enables efficient access to data in JSON'
435 . ' (JavaScript Object Notation) documents'
438 case 'INET6':
439 return __('Intended for storage of IPv6 addresses, as well as IPv4 '
440 . 'addresses assuming conventional mapping of IPv4 addresses '
441 . 'into IPv6 addresses');
444 return '';
448 * Returns class of a type, used for functions available for type
449 * or default values.
451 * @param string $type The data type to get a class.
453 * @return string
455 public function getTypeClass($type)
457 $type = mb_strtoupper((string) $type);
458 switch ($type) {
459 case 'TINYINT':
460 case 'SMALLINT':
461 case 'MEDIUMINT':
462 case 'INT':
463 case 'BIGINT':
464 case 'DECIMAL':
465 case 'FLOAT':
466 case 'DOUBLE':
467 case 'REAL':
468 case 'BIT':
469 case 'BOOLEAN':
470 case 'SERIAL':
471 return 'NUMBER';
473 case 'DATE':
474 case 'DATETIME':
475 case 'TIMESTAMP':
476 case 'TIME':
477 case 'YEAR':
478 return 'DATE';
480 case 'CHAR':
481 case 'VARCHAR':
482 case 'TINYTEXT':
483 case 'TEXT':
484 case 'MEDIUMTEXT':
485 case 'LONGTEXT':
486 case 'BINARY':
487 case 'VARBINARY':
488 case 'TINYBLOB':
489 case 'MEDIUMBLOB':
490 case 'BLOB':
491 case 'LONGBLOB':
492 case 'ENUM':
493 case 'SET':
494 case 'INET6':
495 return 'CHAR';
497 case 'GEOMETRY':
498 case 'POINT':
499 case 'LINESTRING':
500 case 'POLYGON':
501 case 'MULTIPOINT':
502 case 'MULTILINESTRING':
503 case 'MULTIPOLYGON':
504 case 'GEOMETRYCOLLECTION':
505 return 'SPATIAL';
507 case 'JSON':
508 return 'JSON';
511 return '';
515 * Returns array of functions available for a class.
517 * @param string $class The class to get function list.
519 * @return string[]
521 public function getFunctionsClass($class)
523 $isMariaDB = $this->dbi->isMariaDB();
524 $serverVersion = $this->dbi->getVersion();
526 switch ($class) {
527 case 'CHAR':
528 $ret = [
529 'AES_DECRYPT',
530 'AES_ENCRYPT',
531 'BIN',
532 'CHAR',
533 'COMPRESS',
534 'CURRENT_USER',
535 'DATABASE',
536 'DAYNAME',
537 'DES_DECRYPT',
538 'DES_ENCRYPT',
539 'ENCRYPT',
540 'HEX',
541 'INET6_NTOA',
542 'INET_NTOA',
543 'LOAD_FILE',
544 'LOWER',
545 'LTRIM',
546 'MD5',
547 'MONTHNAME',
548 'OLD_PASSWORD',
549 'PASSWORD',
550 'QUOTE',
551 'REVERSE',
552 'RTRIM',
553 'SHA1',
554 'SOUNDEX',
555 'SPACE',
556 'TRIM',
557 'UNCOMPRESS',
558 'UNHEX',
559 'UPPER',
560 'USER',
561 'UUID',
562 'VERSION',
565 if (
566 ($isMariaDB && $serverVersion < 100012)
567 || $serverVersion < 50603
569 $ret = array_diff($ret, ['INET6_NTOA']);
572 return $ret;
574 case 'DATE':
575 return [
576 'CURRENT_DATE',
577 'CURRENT_TIME',
578 'DATE',
579 'FROM_DAYS',
580 'FROM_UNIXTIME',
581 'LAST_DAY',
582 'NOW',
583 'SEC_TO_TIME',
584 'SYSDATE',
585 'TIME',
586 'TIMESTAMP',
587 'UTC_DATE',
588 'UTC_TIME',
589 'UTC_TIMESTAMP',
590 'YEAR',
593 case 'NUMBER':
594 $ret = [
595 'ABS',
596 'ACOS',
597 'ASCII',
598 'ASIN',
599 'ATAN',
600 'BIT_LENGTH',
601 'BIT_COUNT',
602 'CEILING',
603 'CHAR_LENGTH',
604 'CONNECTION_ID',
605 'COS',
606 'COT',
607 'CRC32',
608 'DAYOFMONTH',
609 'DAYOFWEEK',
610 'DAYOFYEAR',
611 'DEGREES',
612 'EXP',
613 'FLOOR',
614 'HOUR',
615 'INET6_ATON',
616 'INET_ATON',
617 'LENGTH',
618 'LN',
619 'LOG',
620 'LOG2',
621 'LOG10',
622 'MICROSECOND',
623 'MINUTE',
624 'MONTH',
625 'OCT',
626 'ORD',
627 'PI',
628 'QUARTER',
629 'RADIANS',
630 'RAND',
631 'ROUND',
632 'SECOND',
633 'SIGN',
634 'SIN',
635 'SQRT',
636 'TAN',
637 'TO_DAYS',
638 'TO_SECONDS',
639 'TIME_TO_SEC',
640 'UNCOMPRESSED_LENGTH',
641 'UNIX_TIMESTAMP',
642 'UUID_SHORT',
643 'WEEK',
644 'WEEKDAY',
645 'WEEKOFYEAR',
646 'YEARWEEK',
648 if (
649 ($isMariaDB && $serverVersion < 100012)
650 || $serverVersion < 50603
652 $ret = array_diff($ret, ['INET6_ATON']);
655 return $ret;
657 case 'SPATIAL':
658 if ($serverVersion >= 50600) {
659 return [
660 'ST_GeomFromText',
661 'ST_GeomFromWKB',
663 'ST_GeomCollFromText',
664 'ST_LineFromText',
665 'ST_MLineFromText',
666 'ST_PointFromText',
667 'ST_MPointFromText',
668 'ST_PolyFromText',
669 'ST_MPolyFromText',
671 'ST_GeomCollFromWKB',
672 'ST_LineFromWKB',
673 'ST_MLineFromWKB',
674 'ST_PointFromWKB',
675 'ST_MPointFromWKB',
676 'ST_PolyFromWKB',
677 'ST_MPolyFromWKB',
681 return [
682 'GeomFromText',
683 'GeomFromWKB',
685 'GeomCollFromText',
686 'LineFromText',
687 'MLineFromText',
688 'PointFromText',
689 'MPointFromText',
690 'PolyFromText',
691 'MPolyFromText',
693 'GeomCollFromWKB',
694 'LineFromWKB',
695 'MLineFromWKB',
696 'PointFromWKB',
697 'MPointFromWKB',
698 'PolyFromWKB',
699 'MPolyFromWKB',
703 return [];
707 * Returns array of functions available for a type.
709 * @param string $type The data type to get function list.
711 * @return string[]
713 public function getFunctions($type)
715 $class = $this->getTypeClass($type);
717 return $this->getFunctionsClass($class);
721 * Returns array of all functions available.
723 * @return string[]
725 public function getAllFunctions()
727 $ret = array_merge(
728 $this->getFunctionsClass('CHAR'),
729 $this->getFunctionsClass('NUMBER'),
730 $this->getFunctionsClass('DATE'),
731 $this->getFunctionsClass('UUID')
733 sort($ret);
735 return $ret;
739 * Returns array of all attributes available.
741 * @return string[]
743 public function getAttributes()
745 return [
747 'BINARY',
748 'UNSIGNED',
749 'UNSIGNED ZEROFILL',
750 'on update CURRENT_TIMESTAMP',
755 * Returns array of all column types available.
757 * VARCHAR, TINYINT, TEXT and DATE are listed first, based on
758 * estimated popularity.
760 * @return array
762 public function getColumns(): array
764 $isMariaDB = $this->dbi->isMariaDB();
765 $serverVersion = $this->dbi->getVersion();
767 // most used types
768 $ret = [
769 'INT',
770 'VARCHAR',
771 'TEXT',
772 'DATE',
774 // numeric
775 $ret[_pgettext('numeric types', 'Numeric')] = [
776 'TINYINT',
777 'SMALLINT',
778 'MEDIUMINT',
779 'INT',
780 'BIGINT',
781 '-',
782 'DECIMAL',
783 'FLOAT',
784 'DOUBLE',
785 'REAL',
786 '-',
787 'BIT',
788 'BOOLEAN',
789 'SERIAL',
792 // Date/Time
793 $ret[_pgettext('date and time types', 'Date and time')] = [
794 'DATE',
795 'DATETIME',
796 'TIMESTAMP',
797 'TIME',
798 'YEAR',
801 // Text
802 $ret[_pgettext('string types', 'String')] = [
803 'CHAR',
804 'VARCHAR',
805 '-',
806 'TINYTEXT',
807 'TEXT',
808 'MEDIUMTEXT',
809 'LONGTEXT',
810 '-',
811 'BINARY',
812 'VARBINARY',
813 '-',
814 'TINYBLOB',
815 'BLOB',
816 'MEDIUMBLOB',
817 'LONGBLOB',
818 '-',
819 'ENUM',
820 'SET',
823 $ret[_pgettext('spatial types', 'Spatial')] = [
824 'GEOMETRY',
825 'POINT',
826 'LINESTRING',
827 'POLYGON',
828 'MULTIPOINT',
829 'MULTILINESTRING',
830 'MULTIPOLYGON',
831 'GEOMETRYCOLLECTION',
834 if (
835 ($isMariaDB && $serverVersion > 100207)
836 || (! $isMariaDB && $serverVersion >= 50708)
838 $ret['JSON'] = ['JSON'];
841 if ($isMariaDB && $serverVersion >= 100500) {
842 array_push($ret[_pgettext('string types', 'String')], '-', 'INET6');
845 return $ret;
849 * Returns an array of integer types
851 * @return string[] integer types
853 public function getIntegerTypes()
855 return [
856 'tinyint',
857 'smallint',
858 'mediumint',
859 'int',
860 'bigint',
865 * Returns the min and max values of a given integer type
867 * @param string $type integer type
868 * @param bool $signed whether signed
870 * @return string[] min and max values
872 public function getIntegerRange($type, $signed = true)
874 static $min_max_data = [
875 'unsigned' => [
876 'tinyint' => [
877 '0',
878 '255',
880 'smallint' => [
881 '0',
882 '65535',
884 'mediumint' => [
885 '0',
886 '16777215',
888 'int' => [
889 '0',
890 '4294967295',
892 'bigint' => [
893 '0',
894 '18446744073709551615',
897 'signed' => [
898 'tinyint' => [
899 '-128',
900 '127',
902 'smallint' => [
903 '-32768',
904 '32767',
906 'mediumint' => [
907 '-8388608',
908 '8388607',
910 'int' => [
911 '-2147483648',
912 '2147483647',
914 'bigint' => [
915 '-9223372036854775808',
916 '9223372036854775807',
920 $relevantArray = $signed
921 ? $min_max_data['signed']
922 : $min_max_data['unsigned'];
924 return $relevantArray[$type] ?? [