3 * SQL data types definition
6 declare(strict_types
=1);
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
;
18 use function strncasecmp
;
21 * Class holding type definitions for MySQL and MariaDB.
25 /** @var DatabaseInterface Database interface */
29 * @param DatabaseInterface $dbi Database interface instance
31 public function __construct($dbi)
37 * Returns list of unary operators.
41 public function getUnaryOperators()
52 * Check whether operator is unary.
54 * @param string $op operator name
58 public function isUnaryOperator($op)
60 return in_array($op, $this->getUnaryOperators());
64 * Returns list of operators checking for NULL.
68 public function getNullOperators()
77 * ENUM search operators
81 public function getEnumOperators()
90 * TEXT search operators
94 public function getTextOperators()
116 * Number search operators
120 public function getNumberOperators()
141 * Returns operators for given type
143 * @param string $type Type of field
144 * @param bool $null Whether field can be NULL
148 public function getTypeOperators($type, $null)
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());
158 $ret = array_merge($ret, $this->getNumberOperators());
162 $ret = array_merge($ret, $this->getNullOperators());
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)
181 foreach ($this->getTypeOperators($type, $null) as $fc) {
182 if (isset($selectedOperator) && $selectedOperator == $fc) {
183 $selected = ' selected="selected"';
188 $html .= '<option value="' . htmlspecialchars($fc) . '"'
190 . htmlspecialchars($fc) . '</option>';
197 * Returns the data type description.
199 * @param string $type The data type to get a description.
203 public function getTypeDescription($type)
205 $type = mb_strtoupper($type);
209 'A 1-byte integer, signed range is -128 to 127, unsigned range is ' .
215 'A 2-byte integer, signed range is -32,768 to 32,767, unsigned ' .
216 'range is 0 to 65,535'
221 'A 3-byte integer, signed range is -8,388,608 to 8,388,607, ' .
222 'unsigned range is 0 to 16,777,215'
227 'A 4-byte integer, signed range is ' .
228 '-2,147,483,648 to 2,147,483,647, unsigned range is 0 to ' .
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'
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 ' .
248 'A small floating-point number, allowable values are ' .
249 '-3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to ' .
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'
262 'Synonym for DOUBLE (exception: in REAL_AS_FLOAT SQL mode it is ' .
263 'a synonym for FLOAT)'
268 'A bit-field type (M), storing M of bits per value (default is 1, ' .
274 'A synonym for TINYINT(1), a value of zero is considered false, ' .
275 'nonzero values are considered true'
279 return __('An alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE');
283 __('A date, supported range is %1$s to %2$s'),
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'
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)'
304 __('A time, range is %1$s to %2$s'),
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 ' .
318 'A fixed-length (0-255, default 1) string that is always ' .
319 'right-padded with spaces to the specified length when stored'
325 'A variable-length (%s) string, the effective maximum length ' .
326 'is subject to the maximum row size'
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 ' .
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'
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'
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'
361 'Similar to the CHAR type, but stores binary byte strings rather ' .
362 'than non-binary character strings'
367 'Similar to the VARCHAR type, but stores binary byte strings ' .
368 'rather than non-binary character strings'
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'
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 ' .
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'
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'
399 'An enumeration, chosen from the list of up to 65,535 values or ' .
400 "the special '' error value"
404 return __('A single value chosen from a set of up to 64 members');
407 return __('A type that can store a geometry of any type');
410 return __('A point in 2-dimensional space');
413 return __('A curve with linear interpolation between points');
416 return __('A polygon');
419 return __('A collection of points');
421 case 'MULTILINESTRING':
423 'A collection of curves with linear interpolation between points'
427 return __('A collection of polygons');
429 case 'GEOMETRYCOLLECTION':
430 return __('A collection of geometry objects of any type');
434 'Stores and enables efficient access to data in JSON'
435 . ' (JavaScript Object Notation) documents'
439 return __('Intended for storage of IPv6 addresses, as well as IPv4 '
440 . 'addresses assuming conventional mapping of IPv4 addresses '
441 . 'into IPv6 addresses');
448 * Returns class of a type, used for functions available for type
451 * @param string $type The data type to get a class.
455 public function getTypeClass($type)
457 $type = mb_strtoupper((string) $type);
502 case 'MULTILINESTRING':
504 case 'GEOMETRYCOLLECTION':
515 * Returns array of functions available for a class.
517 * @param string $class The class to get function list.
521 public function getFunctionsClass($class)
523 $isMariaDB = $this->dbi
->isMariaDB();
524 $serverVersion = $this->dbi
->getVersion();
566 ($isMariaDB && $serverVersion < 100012)
567 ||
$serverVersion < 50603
569 $ret = array_diff($ret, ['INET6_NTOA']);
640 'UNCOMPRESSED_LENGTH',
649 ($isMariaDB && $serverVersion < 100012)
650 ||
$serverVersion < 50603
652 $ret = array_diff($ret, ['INET6_ATON']);
658 if ($serverVersion >= 50600) {
663 'ST_GeomCollFromText',
671 'ST_GeomCollFromWKB',
707 * Returns array of functions available for a type.
709 * @param string $type The data type to get function list.
713 public function getFunctions($type)
715 $class = $this->getTypeClass($type);
717 return $this->getFunctionsClass($class);
721 * Returns array of all functions available.
725 public function getAllFunctions()
728 $this->getFunctionsClass('CHAR'),
729 $this->getFunctionsClass('NUMBER'),
730 $this->getFunctionsClass('DATE'),
731 $this->getFunctionsClass('UUID')
739 * Returns array of all attributes available.
743 public function getAttributes()
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.
762 public function getColumns(): array
764 $isMariaDB = $this->dbi
->isMariaDB();
765 $serverVersion = $this->dbi
->getVersion();
775 $ret[_pgettext('numeric types', 'Numeric')] = [
793 $ret[_pgettext('date and time types', 'Date and time')] = [
802 $ret[_pgettext('string types', 'String')] = [
823 $ret[_pgettext('spatial types', 'Spatial')] = [
831 'GEOMETRYCOLLECTION',
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');
849 * Returns an array of integer types
851 * @return string[] integer types
853 public function getIntegerTypes()
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 = [
894 '18446744073709551615',
915 '-9223372036854775808',
916 '9223372036854775807',
920 $relevantArray = $signed
921 ?
$min_max_data['signed']
922 : $min_max_data['unsigned'];
924 return $relevantArray[$type] ??
[