Skip to content

Commit 2c1124c

Browse files
committed
Fixed a couple of minor bugs in partition parsing.
'MAXVALUE' can be used for partitions. The correct class is used for parsing. Options may be specified for the class that is used for parsing. Wrote tests.
1 parent 3cbebbe commit 2c1124c

9 files changed

Lines changed: 180 additions & 10 deletions

File tree

src/Components/ArrayObj.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ public static function parse(Parser $parser, TokensList $list, array $options =
115115
$ret->values[] = $token->value;
116116
$ret->raw[] = $token->token;
117117
} else {
118-
$ret[] = $options['type']::parse($parser, $list);
118+
$ret[] = $options['type']::parse(
119+
$parser,
120+
$list,
121+
empty($options['typeOptions']) ? array() : $options['typeOptions']
122+
);
119123
}
120124
$state = 2;
121125
} elseif ($state === 2) {

src/Components/PartitionDefinition.php

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,18 @@ public static function parse(Parser $parser, TokensList $list, array $options =
155155
$ret->type = $token->value;
156156
$state = 4;
157157
} elseif ($state === 4) {
158-
$ret->expr = Expression::parse($parser, $list, array('noAlias' => true, 'bracketsDelimited' => true));
158+
if ($token->value === 'MAXVALUE') {
159+
$ret->expr = $token->value;
160+
} else {
161+
$ret->expr = Expression::parse(
162+
$parser,
163+
$list,
164+
array(
165+
'bracketsDelimited' => true,
166+
'noAlias' => true,
167+
)
168+
);
169+
}
159170
$state = 5;
160171
} elseif ($state === 5) {
161172
$ret->options = OptionsArray::parse($parser, $list, static::$OPTIONS);
@@ -166,12 +177,12 @@ public static function parse(Parser $parser, TokensList $list, array $options =
166177
$parser,
167178
$list,
168179
array(
169-
'type' => 'SqlParser\Components\PartitionDefinition'
180+
'type' => 'SqlParser\\Components\\PartitionDefinition'
170181
)
171182
);
172-
} else {
173-
break;
183+
++$list->idx;
174184
}
185+
break;
175186
}
176187
}
177188

@@ -196,11 +207,10 @@ public static function build($component)
196207
if ($component->isSubpartition) {
197208
return 'SUBPARTITION ' . $component->name;
198209
} else {
199-
if (!empty($component->subpartitions)) {
200-
$subpartitions = ' ' . PartitionDefinition::build($component->subpartitions);
201-
}
210+
$subpartitions = empty($component->subpartitions)
211+
? '' : ' ' . PartitionDefinition::build($component->subpartitions);
202212
return 'PARTITION ' . $component->name
203-
. ' VALUES ' . $component->type . $component->expr
213+
. ' VALUES ' . $component->type . ' ' . $component->expr
204214
. $subpartitions;
205215
}
206216

src/Statements/CreateStatement.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,9 +421,11 @@ public function parse(Parser $parser, TokensList $list)
421421
$brackets = false;
422422
} elseif (($token->type === Token::TYPE_KEYWORD) && ($token->value === 'PARTITIONS')) {
423423
$token = $list->getNextOfType(Token::TYPE_NUMBER);
424+
--$list->idx; // `getNextOfType` also advances one position.
424425
$this->partitionsNum = $token->value;
425426
} elseif (($token->type === Token::TYPE_KEYWORD) && ($token->value === 'SUBPARTITIONS')) {
426427
$token = $list->getNextOfType(Token::TYPE_NUMBER);
428+
--$list->idx; // `getNextOfType` also advances one position.
427429
$this->subpartitionsNum = $token->value;
428430
} elseif (!empty($field)) {
429431

@@ -457,7 +459,9 @@ public function parse(Parser $parser, TokensList $list)
457459
$this->partitions = ArrayObj::parse(
458460
$parser,
459461
$list,
460-
array('type' => 'SqlParser\Components\PartitionDefinition')
462+
array(
463+
'type' => 'SqlParser\\Components\\PartitionDefinition'
464+
)
461465
);
462466
}
463467
break;

tests/Builder/CreateStatementTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,34 @@ public function testBuilderTable()
6565
);
6666
}
6767

68+
public function testBuilderPartitions()
69+
{
70+
$query = 'CREATE TABLE ts (' . "\n"
71+
. '`id` INT,' . "\n"
72+
. '`purchased` DATE' . "\n"
73+
. ') ' . "\n"
74+
. 'PARTITION BY RANGE(YEAR(purchased))' . "\n"
75+
. 'PARTITIONS 3' . "\n"
76+
. 'SUBPARTITION BY HASH(TO_DAYS(purchased))' . "\n"
77+
. 'SUBPARTITIONS 2' . "\n"
78+
. '(' . "\n"
79+
. 'PARTITION p0 VALUES LESS THAN (1990) (' . "\n"
80+
. 'SUBPARTITION s0,' . "\n"
81+
. 'SUBPARTITION s1' . "\n"
82+
. '),' . "\n"
83+
. 'PARTITION p1 VALUES LESS THAN (2000) (' . "\n"
84+
. 'SUBPARTITION s2,' . "\n"
85+
. 'SUBPARTITION s3' . "\n"
86+
. '),' . "\n"
87+
. 'PARTITION p2 VALUES LESS THAN MAXVALUE (' . "\n"
88+
. 'SUBPARTITION s4,' . "\n"
89+
. 'SUBPARTITION s5' . "\n"
90+
. ')' . "\n"
91+
. ')';
92+
$parser = new Parser($query);
93+
$this->assertEquals($query, $parser->statements[0]->build());
94+
}
95+
6896
public function testBuilderView()
6997
{
7098
$parser = new Parser(

tests/Components/ArrayObjTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace SqlParser\Tests\Components;
44

5+
use SqlParser\Parser;
56
use SqlParser\Components\ArrayObj;
67

78
use SqlParser\Tests\TestCase;
@@ -21,6 +22,22 @@ public function testBuildValues()
2122
$this->assertEquals('(a, b)', ArrayObj::build($component));
2223
}
2324

25+
public function testParseType()
26+
{
27+
$components = ArrayObj::parse(
28+
new Parser(),
29+
$this->getTokensList('(1 + 2, 3 + 4)'),
30+
array(
31+
'type' => 'SqlParser\\Components\\Expression',
32+
'typeOptions' => array(
33+
'noBrackets' => true,
34+
),
35+
)
36+
);
37+
$this->assertEquals($components[0]->expr, '1 + 2');
38+
$this->assertEquals($components[1]->expr, '3 + 4');
39+
}
40+
2441
/**
2542
* @dataProvider testParseProvider
2643
*/
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace SqlParser\Tests\Components;
4+
5+
use SqlParser\Parser;
6+
use SqlParser\Components\PartitionDefinition;
7+
8+
use SqlParser\Tests\TestCase;
9+
10+
class PartitionDefinitionTest extends TestCase
11+
{
12+
13+
public function testParse()
14+
{
15+
$component = PartitionDefinition::parse(
16+
new Parser(),
17+
$this->getTokensList('PARTITION p0 VALUES LESS THAN(1990)')
18+
);
19+
$this->assertFalse($component->isSubpartition);
20+
$this->assertEquals('p0', $component->name);
21+
$this->assertEquals('LESS THAN', $component->type);
22+
$this->assertEquals('(1990)', $component->expr->expr);
23+
}
24+
}

tests/Parser/CreateStatementTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public function testCreateProvider()
2626
array('parser/parseCreateTable'),
2727
array('parser/parseCreateTable2'),
2828
array('parser/parseCreateTable3'),
29+
array('parser/parseCreateTable4'),
2930
array('parser/parseCreateTableErr1'),
3031
array('parser/parseCreateTableErr2'),
3132
array('parser/parseCreateTrigger'),
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
CREATE TABLE ts(id INT, purchased DATE)
2+
PARTITION BY /* comment */ RANGE(YEAR(purchased))
3+
PARTITIONS 3
4+
SUBPARTITION BY HASH(TO_DAYS(purchased))
5+
SUBPARTITIONS 2(
6+
PARTITION p0
7+
VALUES LESS THAN(1990)(
8+
SUBPARTITION s0,
9+
SUBPARTITION s1
10+
),
11+
PARTITION p1
12+
VALUES LESS THAN(2000)(
13+
SUBPARTITION s2,
14+
SUBPARTITION s3
15+
),
16+
PARTITION p2
17+
VALUES LESS THAN MAXVALUE(
18+
SUBPARTITION s4,
19+
SUBPARTITION s5
20+
)
21+
);

0 commit comments

Comments
 (0)