Pull-request: #17860 Fixes: #17793 Signed-off-by: William Desportes <williamdes@wdes.fr>
This commit is contained in:
commit
5e1ff822f3
@ -84,7 +84,7 @@ final class ColumnsDefinition
|
||||
]
|
||||
);
|
||||
if (isset($_POST['field_where'])) {
|
||||
$form_params['after_field'] = $_POST['after_field'];
|
||||
$form_params['after_field'] = (string) $_POST['after_field'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,6 +246,8 @@ final class ColumnsDefinition
|
||||
case 'NULL':
|
||||
case 'CURRENT_TIMESTAMP':
|
||||
case 'current_timestamp()':
|
||||
case 'UUID':
|
||||
case 'uuid()':
|
||||
$columnMeta['Default'] = $columnMeta['DefaultType'];
|
||||
break;
|
||||
}
|
||||
@ -282,38 +284,8 @@ final class ColumnsDefinition
|
||||
$columnMeta['Expression'] = is_array($expressions) ? $expressions[$columnMeta['Field']] : null;
|
||||
}
|
||||
|
||||
switch ($columnMeta['Default']) {
|
||||
case null:
|
||||
if ($columnMeta['Default'] === null) {
|
||||
if ($columnMeta['Null'] === 'YES') {
|
||||
$columnMeta['DefaultType'] = 'NULL';
|
||||
$columnMeta['DefaultValue'] = '';
|
||||
} else {
|
||||
$columnMeta['DefaultType'] = 'NONE';
|
||||
$columnMeta['DefaultValue'] = '';
|
||||
}
|
||||
} else { // empty
|
||||
$columnMeta['DefaultType'] = 'USER_DEFINED';
|
||||
$columnMeta['DefaultValue'] = $columnMeta['Default'];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'CURRENT_TIMESTAMP':
|
||||
case 'current_timestamp()':
|
||||
$columnMeta['DefaultType'] = 'CURRENT_TIMESTAMP';
|
||||
$columnMeta['DefaultValue'] = '';
|
||||
break;
|
||||
default:
|
||||
$columnMeta['DefaultType'] = 'USER_DEFINED';
|
||||
$columnMeta['DefaultValue'] = $columnMeta['Default'];
|
||||
|
||||
if (substr($columnMeta['Type'], -4) === 'text') {
|
||||
$textDefault = substr($columnMeta['Default'], 1, -1);
|
||||
$columnMeta['Default'] = stripcslashes($textDefault);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
$columnMetaDefault = self::decorateColumnMetaDefault($columnMeta);
|
||||
$columnMeta = array_merge($columnMeta, $columnMetaDefault);
|
||||
}
|
||||
|
||||
if (isset($columnMeta['Type'])) {
|
||||
@ -366,14 +338,10 @@ final class ColumnsDefinition
|
||||
}
|
||||
|
||||
// old column type
|
||||
if (isset($columnMeta['Type'])) {
|
||||
// keep in uppercase because the new type will be in uppercase
|
||||
$form_params['field_type_orig[' . $columnNumber . ']'] = mb_strtoupper($type);
|
||||
if (isset($columnMeta['column_status']) && ! $columnMeta['column_status']['isEditable']) {
|
||||
$form_params['field_type[' . $columnNumber . ']'] = mb_strtoupper($type);
|
||||
}
|
||||
} else {
|
||||
$form_params['field_type_orig[' . $columnNumber . ']'] = '';
|
||||
// keep in uppercase because the new type will be in uppercase
|
||||
$form_params['field_type_orig[' . $columnNumber . ']'] = mb_strtoupper($type);
|
||||
if (isset($columnMeta['column_status']) && ! $columnMeta['column_status']['isEditable']) {
|
||||
$form_params['field_type[' . $columnNumber . ']'] = mb_strtoupper($type);
|
||||
}
|
||||
|
||||
// old column length
|
||||
@ -439,9 +407,11 @@ final class ColumnsDefinition
|
||||
}
|
||||
|
||||
if ($type_upper === 'BIT') {
|
||||
$default_value = Util::convertBitDefaultValue($columnMeta['DefaultValue']);
|
||||
$default_value = ! empty($columnMeta['DefaultValue'])
|
||||
? Util::convertBitDefaultValue($columnMeta['DefaultValue'])
|
||||
: '';
|
||||
} elseif ($type_upper === 'BINARY' || $type_upper === 'VARBINARY') {
|
||||
$default_value = bin2hex($columnMeta['DefaultValue']);
|
||||
$default_value = bin2hex((string) $columnMeta['DefaultValue']);
|
||||
}
|
||||
|
||||
$content_cells[$columnNumber] = [
|
||||
@ -522,4 +492,52 @@ final class ColumnsDefinition
|
||||
'disable_is' => $cfg['Server']['DisableIS'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default type and default value according to the column metadata
|
||||
*
|
||||
* @param array $columnMeta Column Metadata
|
||||
* @phpstan-param array<string, string|null> $columnMeta
|
||||
*
|
||||
* @return non-empty-array<array-key, mixed>
|
||||
*/
|
||||
public static function decorateColumnMetaDefault(array $columnMeta): array
|
||||
{
|
||||
$metaDefault = [
|
||||
'DefaultType' => 'USER_DEFINED',
|
||||
'DefaultValue' => '',
|
||||
];
|
||||
|
||||
switch ($columnMeta['Default']) {
|
||||
case null:
|
||||
if ($columnMeta['Null'] === 'YES') {
|
||||
$metaDefault['DefaultType'] = 'NULL';
|
||||
} else {
|
||||
$metaDefault['DefaultType'] = 'NONE';
|
||||
}
|
||||
|
||||
break;
|
||||
case 'CURRENT_TIMESTAMP':
|
||||
case 'current_timestamp()':
|
||||
$metaDefault['DefaultType'] = 'CURRENT_TIMESTAMP';
|
||||
|
||||
break;
|
||||
case 'UUID':
|
||||
case 'uuid()':
|
||||
$metaDefault['DefaultType'] = 'UUID';
|
||||
|
||||
break;
|
||||
default:
|
||||
$metaDefault['DefaultValue'] = $columnMeta['Default'];
|
||||
|
||||
if (substr((string) $columnMeta['Type'], -4) === 'text') {
|
||||
$textDefault = substr($columnMeta['Default'], 1, -1);
|
||||
$metaDefault['Default'] = stripcslashes($textDefault);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $metaDefault;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1590,38 +1590,21 @@ class InsertEditTest extends AbstractTestCase
|
||||
|
||||
/**
|
||||
* Test for getSpecialCharsAndBackupFieldForInsertingMode
|
||||
*
|
||||
* @param array $column Column parameters
|
||||
* @param array $expected Expected result
|
||||
* @psalm-param array<string, string|bool|null> $column
|
||||
* @psalm-param array<bool|string> $expected
|
||||
*
|
||||
* @dataProvider providerForTestGetSpecialCharsAndBackupFieldForInsertingMode
|
||||
*/
|
||||
public function testGetSpecialCharsAndBackupFieldForInsertingMode(): void
|
||||
{
|
||||
$column = [];
|
||||
$column['True_Type'] = 'bit';
|
||||
$column['Default'] = 'b\'101\'';
|
||||
$column['is_binary'] = true;
|
||||
public function testGetSpecialCharsAndBackupFieldForInsertingMode(
|
||||
array $column,
|
||||
array $expected
|
||||
): void {
|
||||
$GLOBALS['cfg']['ProtectBinary'] = false;
|
||||
$GLOBALS['cfg']['ShowFunctionFields'] = true;
|
||||
|
||||
$result = $this->callFunction(
|
||||
$this->insertEdit,
|
||||
InsertEdit::class,
|
||||
'getSpecialCharsAndBackupFieldForInsertingMode',
|
||||
[$column]
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
false,
|
||||
'b\'101\'',
|
||||
'101',
|
||||
'',
|
||||
'101',
|
||||
],
|
||||
$result
|
||||
);
|
||||
|
||||
// case 2
|
||||
unset($column['Default']);
|
||||
$column['True_Type'] = 'char';
|
||||
|
||||
$result = (array) $this->callFunction(
|
||||
$this->insertEdit,
|
||||
InsertEdit::class,
|
||||
@ -1630,17 +1613,128 @@ class InsertEditTest extends AbstractTestCase
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
true,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
],
|
||||
$expected,
|
||||
$result
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test getSpecialCharsAndBackupFieldForInsertingMode()
|
||||
*
|
||||
* @return array
|
||||
* @psalm-return array<string, array{array<string, string|bool|null>, array<bool|string>}>
|
||||
*/
|
||||
public function providerForTestGetSpecialCharsAndBackupFieldForInsertingMode(): array
|
||||
{
|
||||
return [
|
||||
'bit' => [
|
||||
[
|
||||
'True_Type' => 'bit',
|
||||
'Default' => 'b\'101\'',
|
||||
'is_binary' => true,
|
||||
],
|
||||
[
|
||||
false,
|
||||
'b\'101\'',
|
||||
'101',
|
||||
'',
|
||||
'101',
|
||||
],
|
||||
],
|
||||
'char' => [
|
||||
[
|
||||
'True_Type' => 'char',
|
||||
'is_binary' => true,
|
||||
],
|
||||
[
|
||||
true,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
],
|
||||
],
|
||||
'time with CURRENT_TIMESTAMP value' => [
|
||||
[
|
||||
'True_Type' => 'time',
|
||||
'Default' => 'CURRENT_TIMESTAMP',
|
||||
],
|
||||
[
|
||||
false,
|
||||
'CURRENT_TIMESTAMP',
|
||||
'CURRENT_TIMESTAMP',
|
||||
'',
|
||||
'CURRENT_TIMESTAMP',
|
||||
],
|
||||
],
|
||||
'time with current_timestamp() value' => [
|
||||
[
|
||||
'True_Type' => 'time',
|
||||
'Default' => 'current_timestamp()',
|
||||
],
|
||||
[
|
||||
false,
|
||||
'current_timestamp()',
|
||||
'current_timestamp()',
|
||||
'',
|
||||
'current_timestamp()',
|
||||
],
|
||||
],
|
||||
'time with no dot value' => [
|
||||
[
|
||||
'True_Type' => 'time',
|
||||
'Default' => '10',
|
||||
],
|
||||
[
|
||||
false,
|
||||
'10',
|
||||
'10.000000',
|
||||
'',
|
||||
'10.000000',
|
||||
],
|
||||
],
|
||||
'time with dot value' => [
|
||||
[
|
||||
'True_Type' => 'time',
|
||||
'Default' => '10.08',
|
||||
],
|
||||
[
|
||||
false,
|
||||
'10.08',
|
||||
'10.080000',
|
||||
'',
|
||||
'10.080000',
|
||||
],
|
||||
],
|
||||
'any text with escape text default' => [
|
||||
[
|
||||
'True_Type' => 'text',
|
||||
'Default' => '"lorem\"ipsem"',
|
||||
],
|
||||
[
|
||||
false,
|
||||
'"lorem\"ipsem"',
|
||||
'lorem"ipsem',
|
||||
'',
|
||||
'lorem"ipsem',
|
||||
],
|
||||
],
|
||||
'varchar with html special chars' => [
|
||||
[
|
||||
'True_Type' => 'varchar',
|
||||
'Default' => 'hello world<br><b>lorem</b> ipsem',
|
||||
],
|
||||
[
|
||||
false,
|
||||
'hello world<br><b>lorem</b> ipsem',
|
||||
'hello world<br><b>lorem</b> ipsem',
|
||||
'',
|
||||
'hello world<br><b>lorem</b> ipsem',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for getParamsForUpdateOrInsert
|
||||
*/
|
||||
|
||||
112
test/classes/Table/ColumnsDefinitionTest.php
Normal file
112
test/classes/Table/ColumnsDefinitionTest.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Table;
|
||||
|
||||
use PhpMyAdmin\Table\ColumnsDefinition;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\Table\ColumnsDefinition
|
||||
*/
|
||||
class ColumnsDefinitionTest extends AbstractTestCase
|
||||
{
|
||||
/**
|
||||
* test for ColumnsDefinition::decorateColumnMetaDefault
|
||||
*
|
||||
* @param array $columnMeta column metadata
|
||||
* @param array $expected expected result
|
||||
* @phpstan-param array<string, string|null> $columnMeta
|
||||
* @phpstan-param array<string, string> $expected
|
||||
*
|
||||
* @dataProvider providerColumnMetaDefault
|
||||
*/
|
||||
public function testDecorateColumnMetaDefault(array $columnMeta, array $expected): void
|
||||
{
|
||||
$result = ColumnsDefinition::decorateColumnMetaDefault($columnMeta);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testDecorateColumnMetaDefault
|
||||
*
|
||||
* @return array
|
||||
* @psalm-return array<string, array{array<string, string|null>, array<string, string>}>
|
||||
*/
|
||||
public function providerColumnMetaDefault(): array
|
||||
{
|
||||
return [
|
||||
'when Default is null and Null is YES' => [
|
||||
[
|
||||
'Default' => null,
|
||||
'Null' => 'YES',
|
||||
],
|
||||
[
|
||||
'DefaultType' => 'NULL',
|
||||
'DefaultValue' => '',
|
||||
],
|
||||
],
|
||||
'when Default is null and Null is NO' => [
|
||||
[
|
||||
'Default' => null,
|
||||
'Null' => 'NO',
|
||||
],
|
||||
[
|
||||
'DefaultType' => 'NONE',
|
||||
'DefaultValue' => '',
|
||||
],
|
||||
],
|
||||
'when Default is CURRENT_TIMESTAMP' => [
|
||||
['Default' => 'CURRENT_TIMESTAMP'],
|
||||
[
|
||||
'DefaultType' => 'CURRENT_TIMESTAMP',
|
||||
'DefaultValue' => '',
|
||||
],
|
||||
],
|
||||
'when Default is current_timestamp' => [
|
||||
['Default' => 'current_timestamp()'],
|
||||
[
|
||||
'DefaultType' => 'CURRENT_TIMESTAMP',
|
||||
'DefaultValue' => '',
|
||||
],
|
||||
],
|
||||
'when Default is UUID' => [
|
||||
['Default' => 'UUID'],
|
||||
[
|
||||
'DefaultType' => 'UUID',
|
||||
'DefaultValue' => '',
|
||||
],
|
||||
],
|
||||
'when Default is uuid()' => [
|
||||
['Default' => 'uuid()'],
|
||||
[
|
||||
'DefaultType' => 'UUID',
|
||||
'DefaultValue' => '',
|
||||
],
|
||||
],
|
||||
'when Default is anything else and Type is text' => [
|
||||
[
|
||||
'Default' => '"some\/thing"',
|
||||
'Type' => 'text',
|
||||
],
|
||||
[
|
||||
'Default' => 'some/thing',
|
||||
'DefaultType' => 'USER_DEFINED',
|
||||
'DefaultValue' => '"some\/thing"',
|
||||
],
|
||||
],
|
||||
'when Default is anything else and Type is not text' => [
|
||||
[
|
||||
'Default' => '"some\/thing"',
|
||||
'Type' => 'something',
|
||||
],
|
||||
[
|
||||
'DefaultType' => 'USER_DEFINED',
|
||||
'DefaultValue' => '"some\/thing"',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user