-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIndex.php
More file actions
77 lines (73 loc) · 3.21 KB
/
Copy pathIndex.php
File metadata and controls
77 lines (73 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
namespace Utopia\Query\Schema;
use Utopia\Query\Exception\ValidationException;
use Utopia\Query\Schema\ClickHouse\IndexAlgorithm;
readonly class Index
{
/**
* @param string[] $columns
* @param array<string, int> $lengths
* @param array<string, string> $orders
* @param array<string, string> $collations Column-specific collations (column name => collation)
* @param list<string> $rawColumns Raw SQL expressions appended to the column list (bypass quoting)
* @param list<string|int|float> $algorithmArgs ClickHouse skip-index algorithm args
* (e.g. [3] for set(3),
* [0.01] for bloom_filter(0.01),
* [4, 1024, 3, 0] for ngrambf_v1(n, size_bytes, hashes, seed))
*/
public function __construct(
public string $name,
public array $columns,
public IndexType $type = IndexType::Index,
public array $lengths = [],
public array $orders = [],
public string $method = '',
public string $operatorClass = '',
public array $collations = [],
public array $rawColumns = [],
public ?IndexAlgorithm $algorithm = null,
public array $algorithmArgs = [],
public int $granularity = 1,
) {
// Only ClickHouse data-skipping indexes require an unquoted identifier
// for the name; other dialects emit the name backtick-quoted, so
// hyphens, dots, and other characters are valid there.
if ($algorithm !== null && ! \preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $name)) {
throw new ValidationException('Invalid index name: ' . $name);
}
if ($columns === [] && $rawColumns === []) {
throw new ValidationException('Index requires at least one column.');
}
if ($method !== '' && ! \preg_match('/^[A-Za-z0-9_]+$/', $method)) {
throw new ValidationException('Invalid index method: ' . $method);
}
if ($operatorClass !== '' && ! \preg_match('/^[A-Za-z0-9_.]+$/', $operatorClass)) {
throw new ValidationException('Invalid operator class: ' . $operatorClass);
}
foreach ($collations as $collation) {
if (! \preg_match('/^[A-Za-z0-9_]+$/', $collation)) {
throw new ValidationException('Invalid collation: ' . $collation);
}
}
if ($granularity < 1) {
throw new ValidationException('Index granularity must be >= 1.');
}
if ($algorithm !== null && $algorithmArgs !== [] && ! self::algorithmAcceptsArgs($algorithm)) {
throw new ValidationException(
$algorithm->value . ' does not accept algorithm arguments.'
);
}
}
/**
* MinMax and Inverted are emitted without parentheses in ClickHouse DDL;
* passing args to them would produce invalid SQL.
*/
private static function algorithmAcceptsArgs(IndexAlgorithm $algorithm): bool
{
return match ($algorithm) {
IndexAlgorithm::MinMax,
IndexAlgorithm::Inverted => false,
default => true,
};
}
}