Translated using Weblate (Portuguese)
[phpmyadmin.git] / src / Types.php
blob605698a2029ed5d1ee866bd462068362e41de640
1 <?php
2 /**
3 * SQL data types definition
4 */
6 declare(strict_types=1);
8 namespace PhpMyAdmin;
10 use PhpMyAdmin\Query\Compatibility;
12 use function __;
13 use function _pgettext;
14 use function array_diff;
15 use function array_merge;
16 use function array_values;
17 use function htmlspecialchars;
18 use function in_array;
19 use function mb_strtoupper;
20 use function sort;
21 use function sprintf;
22 use function strncasecmp;
24 /**
25 * Class holding type definitions for MySQL and MariaDB.
27 class Types
29 public function __construct(private DatabaseInterface $dbi)
33 /**
34 * Returns list of unary operators.
36 * @return string[]
38 public function getUnaryOperators(): array
40 return ['IS NULL', 'IS NOT NULL', "= ''", "!= ''"];
43 /**
44 * Check whether operator is unary.
46 * @param string $op operator name
48 public function isUnaryOperator(string $op): bool
50 return in_array($op, $this->getUnaryOperators(), true);
53 /**
54 * Returns list of operators checking for NULL.
56 * @return string[]
58 public function getNullOperators(): array
60 return ['IS NULL', 'IS NOT NULL'];
63 /**
64 * ENUM search operators
66 * @return string[]
68 public function getEnumOperators(): array
70 return ['=', '!='];
73 /**
74 * TEXT search operators
76 * @return string[]
78 public function getTextOperators(): array
80 return [
81 'LIKE',
82 'LIKE %...%',
83 'NOT LIKE',
84 'NOT LIKE %...%',
85 '=',
86 '!=',
87 'REGEXP',
88 'REGEXP ^...$',
89 'NOT REGEXP',
90 "= ''",
91 "!= ''",
92 'IN (...)',
93 'NOT IN (...)',
94 'BETWEEN',
95 'NOT BETWEEN',
99 /**
100 * Number search operators
102 * @return string[]
104 public function getNumberOperators(): array
106 return [
107 '=',
108 '>',
109 '>=',
110 '<',
111 '<=',
112 '!=',
113 'LIKE',
114 'LIKE %...%',
115 'NOT LIKE',
116 'NOT LIKE %...%',
117 'IN (...)',
118 'NOT IN (...)',
119 'BETWEEN',
120 'NOT BETWEEN',
125 * UUID search operators
127 * @return string[]
129 public function getUUIDOperators(): array
131 return ['=', '!=', 'LIKE', 'LIKE %...%', 'NOT LIKE', 'NOT LIKE %...%', 'IN (...)', 'NOT IN (...)'];
135 * Returns operators for given type
137 * @param string $type Type of field
138 * @param bool $null Whether field can be NULL
140 * @return string[]
142 public function getTypeOperators(string $type, bool $null): array
144 $ret = [];
145 $class = $this->getTypeClass($type);
147 if (strncasecmp($type, 'enum', 4) == 0) {
148 $ret = array_merge($ret, $this->getEnumOperators());
149 } elseif ($class === 'CHAR') {
150 $ret = array_merge($ret, $this->getTextOperators());
151 } elseif ($class === 'UUID') {
152 $ret = array_merge($ret, $this->getUUIDOperators());
153 } else {
154 $ret = array_merge($ret, $this->getNumberOperators());
157 if ($null) {
158 return array_merge($ret, $this->getNullOperators());
161 return $ret;
165 * Returns operators for given type as html options
167 * @param string $type Type of field
168 * @param bool $null Whether field can be NULL
169 * @param string|null $selectedOperator Option to be selected
171 * @return string Generated Html
173 public function getTypeOperatorsHtml(string $type, bool $null, string|null $selectedOperator = null): string
175 $html = '';
177 foreach ($this->getTypeOperators($type, $null) as $fc) {
178 $selected = $selectedOperator !== null && $selectedOperator === $fc ? ' selected="selected"' : '';
180 $html .= '<option value="' . htmlspecialchars($fc) . '"'
181 . $selected . '>'
182 . htmlspecialchars($fc) . '</option>';
185 return $html;
189 * Returns the data type description.
191 * @param string $type The data type to get a description.
193 public function getTypeDescription(string $type): string
195 return match (mb_strtoupper($type)) {
196 'TINYINT' => __('A 1-byte integer, signed range is -128 to 127, unsigned range is 0 to 255'),
197 'SMALLINT' => __('A 2-byte integer, signed range is -32,768 to 32,767, unsigned range is 0 to 65,535'),
198 'MEDIUMINT' => __(
199 'A 3-byte integer, signed range is -8,388,608 to 8,388,607, unsigned range is 0 to 16,777,215',
201 'INT' => __(
202 'A 4-byte integer, signed range is ' .
203 '-2,147,483,648 to 2,147,483,647, unsigned range is 0 to ' .
204 '4,294,967,295',
206 'BIGINT' => __(
207 'An 8-byte integer, signed range is -9,223,372,036,854,775,808 ' .
208 'to 9,223,372,036,854,775,807, unsigned range is 0 to ' .
209 '18,446,744,073,709,551,615',
211 'DECIMAL' => __(
212 'A fixed-point number (M, D) - the maximum number of digits (M) ' .
213 'is 65 (default 10), the maximum number of decimals (D) is 30 ' .
214 '(default 0)',
216 'FLOAT' => __(
217 'A small floating-point number, allowable values are ' .
218 '-3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to ' .
219 '3.402823466E+38',
221 'DOUBLE' => __(
222 'A double-precision floating-point number, allowable values are ' .
223 '-1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and ' .
224 '2.2250738585072014E-308 to 1.7976931348623157E+308',
226 'REAL' => __('Synonym for DOUBLE (exception: in REAL_AS_FLOAT SQL mode it is a synonym for FLOAT)'),
227 'BIT' => __('A bit-field type (M), storing M of bits per value (default is 1, maximum is 64)'),
228 'BOOLEAN' => __(
229 'A synonym for TINYINT(1), a value of zero is considered false, nonzero values are considered true',
231 'SERIAL' => __('An alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE'),
232 'DATE' => sprintf(
233 __('A date, supported range is %1$s to %2$s'),
234 '1000-01-01',
235 '9999-12-31',
237 'DATETIME' => sprintf(
238 __('A date and time combination, supported range is %1$s to %2$s'),
239 '1000-01-01 00:00:00',
240 '9999-12-31 23:59:59',
242 'TIMESTAMP' => __(
243 'A timestamp, range is 1970-01-01 00:00:01 UTC to 2038-01-09 ' .
244 '03:14:07 UTC, stored as the number of seconds since the epoch ' .
245 '(1970-01-01 00:00:00 UTC)',
247 'TIME' => sprintf(
248 __('A time, range is %1$s to %2$s'),
249 '-838:59:59',
250 '838:59:59',
252 'YEAR' => __(
253 'A year in four-digit (4, default) or two-digit (2) format, the ' .
254 'allowable values are 70 (1970) to 69 (2069) or 1901 to 2155 and ' .
255 '0000',
257 'CHAR' => __(
258 'A fixed-length (0-255, default 1) string that is always ' .
259 'right-padded with spaces to the specified length when stored',
261 'VARCHAR' => sprintf(
263 'A variable-length (%s) string, the effective maximum length is subject to the maximum row size',
265 '0-65,535',
267 'TINYTEXT' => __(
268 'A TEXT column with a maximum length of 255 (2^8 - 1) characters, ' .
269 'stored with a one-byte prefix indicating the length of the value ' .
270 'in bytes',
272 'TEXT' => __(
273 'A TEXT column with a maximum length of 65,535 (2^16 - 1) ' .
274 'characters, stored with a two-byte prefix indicating the length ' .
275 'of the value in bytes',
277 'MEDIUMTEXT' => __(
278 'A TEXT column with a maximum length of 16,777,215 (2^24 - 1) ' .
279 'characters, stored with a three-byte prefix indicating the ' .
280 'length of the value in bytes',
282 'LONGTEXT' => __(
283 'A TEXT column with a maximum length of 4,294,967,295 or 4GiB ' .
284 '(2^32 - 1) characters, stored with a four-byte prefix indicating ' .
285 'the length of the value in bytes',
287 'BINARY' => __(
288 'Similar to the CHAR type, but stores binary byte strings rather than non-binary character strings',
290 'VARBINARY' => __(
291 'Similar to the VARCHAR type, but stores binary byte strings ' .
292 'rather than non-binary character strings',
294 'TINYBLOB' => __(
295 'A BLOB column with a maximum length of 255 (2^8 - 1) bytes, ' .
296 'stored with a one-byte prefix indicating the length of the value',
298 'MEDIUMBLOB' => __(
299 'A BLOB column with a maximum length of 16,777,215 (2^24 - 1) ' .
300 'bytes, stored with a three-byte prefix indicating the length of ' .
301 'the value',
303 'BLOB' => __(
304 'A BLOB column with a maximum length of 65,535 (2^16 - 1) bytes, ' .
305 'stored with a two-byte prefix indicating the length of the value',
307 'LONGBLOB' => __(
308 'A BLOB column with a maximum length of 4,294,967,295 or 4GiB ' .
309 '(2^32 - 1) bytes, stored with a four-byte prefix indicating the ' .
310 'length of the value',
312 'ENUM' => __('An enumeration, chosen from the list of up to 65,535 values or the special \'\' error value'),
313 'SET' => __('A single value chosen from a set of up to 64 members'),
314 'GEOMETRY' => __('A type that can store a geometry of any type'),
315 'POINT' => __('A point in 2-dimensional space'),
316 'LINESTRING' => __('A curve with linear interpolation between points'),
317 'POLYGON' => __('A polygon'),
318 'MULTIPOINT' => __('A collection of points'),
319 'MULTILINESTRING' => __('A collection of curves with linear interpolation between points'),
320 'MULTIPOLYGON' => __('A collection of polygons'),
321 'GEOMETRYCOLLECTION' => __('A collection of geometry objects of any type'),
322 'JSON' => __('Stores and enables efficient access to data in JSON (JavaScript Object Notation) documents'),
323 'INET6' => __('Intended for storage of IPv6 addresses, as well as IPv4 '
324 . 'addresses assuming conventional mapping of IPv4 addresses '
325 . 'into IPv6 addresses'),
326 'UUID' => __('128-bit UUID (Universally Unique Identifier)'),
327 default => '',
332 * Returns class of a type, used for functions available for type
333 * or default values.
335 * @param string $type The data type to get a class.
337 public function getTypeClass(string $type): string
339 return match (mb_strtoupper($type)) {
340 'TINYINT',
341 'SMALLINT',
342 'MEDIUMINT',
343 'INT',
344 'BIGINT',
345 'DECIMAL',
346 'FLOAT',
347 'DOUBLE',
348 'REAL',
349 'BIT',
350 'BOOLEAN',
351 'SERIAL'
352 => 'NUMBER',
353 'DATE',
354 'DATETIME',
355 'TIMESTAMP',
356 'TIME',
357 'YEAR'
358 => 'DATE',
359 'CHAR',
360 'VARCHAR',
361 'TINYTEXT',
362 'TEXT',
363 'MEDIUMTEXT',
364 'LONGTEXT',
365 'BINARY',
366 'VARBINARY',
367 'TINYBLOB',
368 'MEDIUMBLOB',
369 'BLOB',
370 'LONGBLOB',
371 'ENUM',
372 'SET',
373 'INET6'
374 => 'CHAR',
375 'GEOMETRY',
376 'POINT',
377 'LINESTRING',
378 'POLYGON',
379 'MULTIPOINT',
380 'MULTILINESTRING',
381 'MULTIPOLYGON',
382 'GEOMETRYCOLLECTION'
383 => 'SPATIAL',
384 'JSON' => 'JSON',
385 'UUID' => 'UUID',
386 default => '',
391 * Returns array of functions available for a class.
393 * @param string $class The class to get function list.
395 * @return string[]
397 public function getFunctionsClass(string $class): array
399 $isMariaDB = $this->dbi->isMariaDB();
400 $serverVersion = $this->dbi->getVersion();
402 switch ($class) {
403 case 'CHAR':
404 $ret = [
405 'AES_DECRYPT',
406 'AES_ENCRYPT',
407 'BIN',
408 'CHAR',
409 'COMPRESS',
410 'CURRENT_USER',
411 'DATABASE',
412 'DAYNAME',
413 'DES_DECRYPT',
414 'DES_ENCRYPT',
415 'ENCRYPT',
416 'HEX',
417 'INET6_NTOA',
418 'INET_NTOA',
419 'LOAD_FILE',
420 'LOWER',
421 'LTRIM',
422 'MD5',
423 'MONTHNAME',
424 'OLD_PASSWORD',
425 'PASSWORD',
426 'QUOTE',
427 'REVERSE',
428 'RTRIM',
429 'SHA1',
430 'SHA2',
431 'SOUNDEX',
432 'SPACE',
433 'TRIM',
434 'UNCOMPRESS',
435 'UNHEX',
436 'UPPER',
437 'USER',
438 'UUID',
439 'VERSION',
442 if (($isMariaDB && $serverVersion < 100012) || $serverVersion < 50603) {
443 $ret = array_diff($ret, ['INET6_NTOA']);
446 return array_values($ret);
448 case 'DATE':
449 return [
450 'CURRENT_DATE',
451 'CURRENT_TIME',
452 'DATE',
453 'FROM_DAYS',
454 'FROM_UNIXTIME',
455 'LAST_DAY',
456 'NOW',
457 'SEC_TO_TIME',
458 'SYSDATE',
459 'TIME',
460 'TIMESTAMP',
461 'UTC_DATE',
462 'UTC_TIME',
463 'UTC_TIMESTAMP',
464 'YEAR',
467 case 'NUMBER':
468 $ret = [
469 'ABS',
470 'ACOS',
471 'ASCII',
472 'ASIN',
473 'ATAN',
474 'BIT_LENGTH',
475 'BIT_COUNT',
476 'CEILING',
477 'CHAR_LENGTH',
478 'CONNECTION_ID',
479 'COS',
480 'COT',
481 'CRC32',
482 'DAYOFMONTH',
483 'DAYOFWEEK',
484 'DAYOFYEAR',
485 'DEGREES',
486 'EXP',
487 'FLOOR',
488 'HOUR',
489 'INET6_ATON',
490 'INET_ATON',
491 'LENGTH',
492 'LN',
493 'LOG',
494 'LOG2',
495 'LOG10',
496 'MICROSECOND',
497 'MINUTE',
498 'MONTH',
499 'OCT',
500 'ORD',
501 'PI',
502 'QUARTER',
503 'RADIANS',
504 'RAND',
505 'ROUND',
506 'SECOND',
507 'SIGN',
508 'SIN',
509 'SQRT',
510 'TAN',
511 'TO_DAYS',
512 'TO_SECONDS',
513 'TIME_TO_SEC',
514 'UNCOMPRESSED_LENGTH',
515 'UNIX_TIMESTAMP',
516 'UUID_SHORT',
517 'WEEK',
518 'WEEKDAY',
519 'WEEKOFYEAR',
520 'YEARWEEK',
523 if (($isMariaDB && $serverVersion < 100012) || $serverVersion < 50603) {
524 $ret = array_diff($ret, ['INET6_ATON']);
527 return array_values($ret);
529 case 'SPATIAL':
530 if ($serverVersion >= 50600) {
531 return [
532 'ST_GeomFromText',
533 'ST_GeomFromWKB',
535 'ST_GeomCollFromText',
536 'ST_LineFromText',
537 'ST_MLineFromText',
538 'ST_PointFromText',
539 'ST_MPointFromText',
540 'ST_PolyFromText',
541 'ST_MPolyFromText',
543 'ST_GeomCollFromWKB',
544 'ST_LineFromWKB',
545 'ST_MLineFromWKB',
546 'ST_PointFromWKB',
547 'ST_MPointFromWKB',
548 'ST_PolyFromWKB',
549 'ST_MPolyFromWKB',
553 return [
554 'GeomFromText',
555 'GeomFromWKB',
557 'GeomCollFromText',
558 'LineFromText',
559 'MLineFromText',
560 'PointFromText',
561 'MPointFromText',
562 'PolyFromText',
563 'MPolyFromText',
565 'GeomCollFromWKB',
566 'LineFromWKB',
567 'MLineFromWKB',
568 'PointFromWKB',
569 'MPointFromWKB',
570 'PolyFromWKB',
571 'MPolyFromWKB',
575 return [];
579 * Returns array of functions available for a type.
581 * @param string $type The data type to get function list.
583 * @return string[]
585 public function getFunctions(string $type): array
587 $class = $this->getTypeClass($type);
589 return $this->getFunctionsClass($class);
593 * Returns array of all functions available.
595 * @return string[]
597 public function getAllFunctions(): array
599 $ret = array_merge(
600 $this->getFunctionsClass('CHAR'),
601 $this->getFunctionsClass('NUMBER'),
602 $this->getFunctionsClass('DATE'),
603 $this->getFunctionsClass('SPATIAL'),
605 sort($ret);
607 return $ret;
611 * Returns array of all attributes available.
613 * @return string[]
615 public function getAttributes(): array
617 $serverVersion = $this->dbi->getVersion();
619 $attributes = ['', 'BINARY', 'UNSIGNED', 'UNSIGNED ZEROFILL', 'on update CURRENT_TIMESTAMP'];
621 if (Compatibility::supportsCompressedColumns($serverVersion)) {
622 $attributes[] = 'COMPRESSED=zlib';
625 return $attributes;
629 * Returns array of all column types available.
631 * VARCHAR, TINYINT, TEXT and DATE are listed first, based on
632 * estimated popularity.
634 * @return string[]|array<string, string[]>
636 public function getColumns(): array
638 $isMariaDB = $this->dbi->isMariaDB();
639 $serverVersion = $this->dbi->getVersion();
640 $isUUIDSupported = Compatibility::isUUIDSupported($this->dbi);
642 // most used types
643 $ret = ['INT', 'VARCHAR', 'TEXT', 'DATE'];
645 if ($isUUIDSupported) {
646 $ret[] = 'UUID';
649 // numeric
650 $ret[_pgettext('numeric types', 'Numeric')] = [
651 'TINYINT',
652 'SMALLINT',
653 'MEDIUMINT',
654 'INT',
655 'BIGINT',
656 '-',
657 'DECIMAL',
658 'FLOAT',
659 'DOUBLE',
660 'REAL',
661 '-',
662 'BIT',
663 'BOOLEAN',
664 'SERIAL',
667 // Date/Time
668 $ret[_pgettext('date and time types', 'Date and time')] = ['DATE', 'DATETIME', 'TIMESTAMP', 'TIME', 'YEAR'];
670 // Text
671 $stringTypes = [
672 'CHAR',
673 'VARCHAR',
674 '-',
675 'TINYTEXT',
676 'TEXT',
677 'MEDIUMTEXT',
678 'LONGTEXT',
679 '-',
680 'BINARY',
681 'VARBINARY',
682 '-',
683 'TINYBLOB',
684 'BLOB',
685 'MEDIUMBLOB',
686 'LONGBLOB',
687 '-',
688 'ENUM',
689 'SET',
691 if ($isMariaDB && $serverVersion >= 100500) {
692 $stringTypes[] = '-';
693 $stringTypes[] = 'INET6';
696 $ret[_pgettext('string types', 'String')] = $stringTypes;
698 $ret[_pgettext('spatial types', 'Spatial')] = [
699 'GEOMETRY',
700 'POINT',
701 'LINESTRING',
702 'POLYGON',
703 'MULTIPOINT',
704 'MULTILINESTRING',
705 'MULTIPOLYGON',
706 'GEOMETRYCOLLECTION',
709 if (($isMariaDB && $serverVersion > 100207) || (! $isMariaDB && $serverVersion >= 50708)) {
710 $ret['JSON'] = ['JSON'];
713 if ($isUUIDSupported) {
714 $ret['UUID'] = ['UUID'];
717 return $ret;
721 * Returns an array of integer types
723 * @return string[] integer types
725 public function getIntegerTypes(): array
727 return ['tinyint', 'smallint', 'mediumint', 'int', 'bigint'];
730 public function mapAliasToMysqlType(string $alias): string
732 return match ($alias) {
733 'BOOL' => 'TINYINT',
734 'BOOLEAN' => 'TINYINT',
735 'CHARACTER VARYING' => 'VARCHAR',
736 'FIXED' => 'DECIMAL',
737 'FLOAT4' => 'FLOAT',
738 'FLOAT8' => 'DOUBLE',
739 'INT1' => 'TINYINT',
740 'INT2' => 'SMALLINT',
741 'INT3' => 'MEDIUMINT',
742 'INT4' => 'INT',
743 'INT8' => 'BIGINT',
744 'LONG VARBINARY' => 'MEDIUMBLOB',
745 'LONG VARCHAR' => 'MEDIUMTEXT',
746 'LONG' => 'MEDIUMTEXT',
747 'MIDDLEINT' => 'MEDIUMINT',
748 'NUMERIC' => 'DECIMAL',
749 default => $alias,
754 * Returns an array of float types
756 * @return string[] float types
758 public function getFloatTypes(): array
760 return ['decimal', 'float', 'double', 'real'];
764 * Returns the min and max values of a given integer type
766 * @param string $type integer type
767 * @param bool $signed whether signed
769 * @return string[] min and max values
771 public function getIntegerRange(string $type, bool $signed = true): array
773 $minMaxData = [
774 'unsigned' => [
775 'tinyint' => ['0', '255'],
776 'smallint' => ['0', '65535'],
777 'mediumint' => ['0', '16777215'],
778 'int' => ['0', '4294967295'],
779 'bigint' => ['0', '18446744073709551615'],
781 'signed' => [
782 'tinyint' => ['-128', '127'],
783 'smallint' => ['-32768', '32767'],
784 'mediumint' => ['-8388608', '8388607'],
785 'int' => ['-2147483648', '2147483647'],
786 'bigint' => ['-9223372036854775808', '9223372036854775807'],
789 $relevantArray = $signed
790 ? $minMaxData['signed']
791 : $minMaxData['unsigned'];
793 return $relevantArray[$type] ?? ['', ''];