Skip to content

Commit

Permalink
Change layout of index references (#103)
Browse files Browse the repository at this point in the history
* Change layout of index references

* Remove unused code
  • Loading branch information
muglug committed May 18, 2023
1 parent 363db04 commit 6b6fd88
Show file tree
Hide file tree
Showing 24 changed files with 766 additions and 429 deletions.
2 changes: 1 addition & 1 deletion .hhconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
hackfmt.line_width=120
hackfmt.tabs=true
allowed_decl_fixme_codes=2053,3012,4045,4047,4341
allowed_fixme_codes_strict=2011,2049,2050,2053,2083,3012,3084,4027,4038,4045,4047,4104,4105,4106,4107,4108,4110,4128,4135,4188,4223,4240,4323,4341,4390,4401
allowed_fixme_codes_strict=2011,2049,2050,2053,2083,3012,3084,4027,4038,4045,4047,4104,4105,4106,4107,4108,4110,4128,4135,4188,4223,4240,4323,4341,4390,4401,4063,4006
5 changes: 0 additions & 5 deletions src/Expressions/BetweenOperatorExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $conn): bool {
return ($this->negated ? !$eval : $eval) ? true : false;
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

<<__Override>>
public function negate(): void {
$this->negated = true;
Expand Down
63 changes: 7 additions & 56 deletions src/Expressions/BinaryOperatorExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Slack\SQLFake;

use namespace HH\Lib\{C, Dict, Regex, Str, Vec};
use namespace HH\Lib\{C, Regex, Str, Vec};

/**
* any operator that takes arguments on the left and right side, like +, -, *, AND, OR...
Expand Down Expand Up @@ -166,8 +166,9 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $conn): mixed {
}
case Operator::GREATER_THAN:
if ($as_string) {
return
(bool)((((Str\compare((string)$l_value, (string)$r_value)) > 0) ? 1 : 0) ^ $this->negatedInt);
return (bool)(
(((Str\compare((string)$l_value, (string)$r_value)) > 0) ? 1 : 0) ^ $this->negatedInt
);
} else {
return (bool)(((float)$l_value > (float)$r_value) ? 1 : 0 ^ $this->negatedInt);
}
Expand All @@ -180,8 +181,9 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $conn): mixed {
}
case Operator::LESS_THAN:
if ($as_string) {
return
(bool)((((Str\compare((string)$l_value, (string)$r_value)) < 0) ? 1 : 0) ^ $this->negatedInt);
return (bool)(
(((Str\compare((string)$l_value, (string)$r_value)) < 0) ? 1 : 0) ^ $this->negatedInt
);
} else {
return (bool)(((float)$l_value < (float)$r_value) ? 1 : 0 ^ $this->negatedInt);
}
Expand Down Expand Up @@ -309,57 +311,6 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $conn): mixed {
}
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $columns): ?dict<string, mixed> {
$op = $this->operator;
if ($op === null) {
// an operator should only be in this state in the middle of parsing, never when evaluating
throw new SQLFakeRuntimeException('Attempted to evaluate BinaryOperatorExpression with empty operator');
}

if ($this->negated) {
return null;
}

return self::getColumnNamesFromBinop($this, $columns);
}

private static function getColumnNamesFromBinop(
BinaryOperatorExpression $expr,
dict<string, Column> $columns,
): dict<string, mixed> {
$column_names = dict[];

if ($expr->operator === Operator::EQUALS) {
if ($expr->left is ColumnExpression && $expr->left->name !== '*' && $expr->right is ConstantExpression) {
$table_name = $expr->left->tableName;
$column_name = $expr->left->name;
if ($table_name is nonnull) {
$column_name = $table_name.'.'.$column_name;
}
$value = $expr->right->value;
if (isset($columns[$column_name])) {
if ($columns[$column_name]->hack_type === 'int') {
$value = (int)$value;
}
}
$column_names[$column_name] = $value;
}
}

if ($expr->operator === Operator::AND) {
if ($expr->left is BinaryOperatorExpression) {
$column_names = self::getColumnNamesFromBinop($expr->left, $columns);
}

if ($expr->right is BinaryOperatorExpression) {
$column_names = Dict\merge($column_names, self::getColumnNamesFromBinop($expr->right, $columns));
}
}

return $column_names;
}

/**
* Coerce a mixed value to a num,
* but also handle sub-expressions that return a dataset containing a num
Expand Down
5 changes: 0 additions & 5 deletions src/Expressions/CaseOperatorExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $conn): mixed {
return $this->else->evaluate($row, $conn);
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

<<__Override>>
public function isWellFormed(): bool {
return $this->wellFormed;
Expand Down
5 changes: 0 additions & 5 deletions src/Expressions/ColumnExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,6 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $_conn): mixed {
}
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

/**
* for use in ORDER BY... allow evaluating the expression
* to fall through to the full row if the column is not found fully qualified.
Expand Down
5 changes: 0 additions & 5 deletions src/Expressions/ConstantExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ public function evaluateImpl(row $_row, AsyncMysqlConnection $_conn): mixed {
return $this->value;
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

<<__Override>>
public function isWellFormed(): bool {
return true;
Expand Down
2 changes: 0 additions & 2 deletions src/Expressions/Expression.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ final public function evaluate(
return $result;
}

public abstract function getIndexCandidates(dict<string, Column> $columns): ?dict<string, mixed>;

/**
* a lot of times you just want the value
*/
Expand Down
5 changes: 0 additions & 5 deletions src/Expressions/FunctionExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,6 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $conn): mixed {
}
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

public function isAggregate(): bool {
return C\contains_key(keyset['COUNT', 'SUM', 'MIN', 'MAX', 'AVG'], $this->functionName);
}
Expand Down
9 changes: 2 additions & 7 deletions src/Expressions/InOperatorExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
*/
final class InOperatorExpression extends Expression {

private ?vec<Expression> $inList = null;
public ?vec<Expression> $inList = null;

public function __construct(private Expression $left, public bool $negated = false) {
public function __construct(public Expression $left, public bool $negated = false) {
$op = Operator::IN;
$this->name = '';
$this->precedence = ExpressionParser::OPERATOR_PRECEDENCE[operator_to_string($op)];
Expand Down Expand Up @@ -69,11 +69,6 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $conn): bool {
return $this->negated;
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

<<__Override>>
public function negate(): void {
$this->negated = true;
Expand Down
10 changes: 3 additions & 7 deletions src/Expressions/JSONFunctionExpression.hack
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ final class JSONFunctionExpression extends BaseFunctionExpression {
throw new SQLFakeRuntimeException('Function '.$this->functionName.' not implemented yet');
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

private function sqlJSONValid(row $row, AsyncMysqlConnection $conn): ?bool {
$row = $this->maybeUnrollGroupedDataset($row);
$args = $this->args;
Expand Down Expand Up @@ -336,8 +331,9 @@ final class JSONFunctionExpression extends BaseFunctionExpression {

$argCount = C\count($args);
if ($argCount !== 1) {
throw
new SQLFakeRuntimeException('MySQL JSON_DEPTH() function must be called with 1 JSON document argument');
throw new SQLFakeRuntimeException(
'MySQL JSON_DEPTH() function must be called with 1 JSON document argument',
);
}

$json = $args[0]->evaluate($row, $conn);
Expand Down
5 changes: 0 additions & 5 deletions src/Expressions/PlaceholderExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ public function evaluateImpl(row $_row, AsyncMysqlConnection $_conn): mixed {
throw new SQLFakeRuntimeException('Attempted to evaluate placeholder expression!');
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

<<__Override>>
public function isWellFormed(): bool {
return false;
Expand Down
5 changes: 0 additions & 5 deletions src/Expressions/RowExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $conn): mixed {
return $result;
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

<<__Override>>
public function isWellFormed(): bool {
return true;
Expand Down
5 changes: 0 additions & 5 deletions src/Expressions/SubqueryExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $conn): dataset {
return $this->query->execute($conn, $row);
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

<<__Override>>
public function isWellFormed(): bool {
return true;
Expand Down
5 changes: 0 additions & 5 deletions src/Expressions/UnaryExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ public function evaluateImpl(row $row, AsyncMysqlConnection $conn): mixed {
return $val;
}

<<__Override>>
public function getIndexCandidates(dict<string, Column> $_columns): ?dict<string, mixed> {
return null;
}

<<__Override>>
public function setNextChild(Expression $expr, bool $overwrite = false): void {
if ($this->subject is nonnull && !$overwrite) {
Expand Down
38 changes: 23 additions & 15 deletions src/Query/DeleteQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ public function __construct(public string $sql) {}
public function execute(AsyncMysqlConnection $conn): int {
$this->fromClause as nonnull;
list($database, $table_name) = Query::parseTableName($conn, $this->fromClause['name']);
$data = $conn->getServer()->getTableData($database, $table_name) ?? tuple(dict[], dict[], dict[]);
$data = $conn->getServer()->getTableData($database, $table_name) ?? tuple(dict[], dict[]);
$schema = QueryContext::getSchema($database, $table_name);

Metrics::trackQuery(QueryType::DELETE, $conn->getServer()->name, $table_name, $this->sql);

$columns = null;

if ($schema?->fields is nonnull) {
if ($schema is nonnull) {
$columns = dict[];
foreach ($schema?->fields as $field) {
foreach ($schema->fields as $field) {
$columns[$field->name] = $field;
}
}

return $this->applyWhere($conn, $data[0], $data[1], $data[2], $columns, $schema?->indexes)
return $this->applyWhere($conn, $data[0], $data[1], $columns, $schema?->indexes)
|> $this->applyOrderBy($conn, $$)
|> $this->applyLimit($$)
|> $this->applyDelete($conn, $database, $table_name, $$, $data[0], $data[1], $data[2], $schema);
|> $this->applyDelete($conn, $database, $table_name, $$, $data[0], $data[1], $schema);
}

/**
Expand All @@ -41,7 +41,6 @@ protected function applyDelete(
string $table_name,
dataset $filtered_rows,
dataset $original_table,
unique_index_refs $unique_index_refs,
index_refs $index_refs,
?TableSchema $table_schema,
): int {
Expand All @@ -51,22 +50,31 @@ protected function applyDelete(
$rows_affected = C\count($original_table) - C\count($remaining_rows);

if ($table_schema is nonnull) {
foreach ($filtered_rows as $row_id => $row_to_delete) {
list($unique_index_ref_deletes, $index_ref_deletes) =
self::getIndexRemovalsForRow($table_schema->indexes, $row_id, $row_to_delete);
$applicable_indexes = $table_schema->indexes;

foreach ($unique_index_ref_deletes as list($index_name, $index_key)) {
unset($unique_index_refs[$index_name][$index_key]);
}
if ($table_schema->vitess_sharding) {
$applicable_indexes[] = new Index(
$table_schema->vitess_sharding->keyspace,
'INDEX',
keyset[$table_schema->vitess_sharding->sharding_key],
);
}

foreach ($filtered_rows as $row_id => $row_to_delete) {
$index_ref_deletes = self::getIndexModificationsForRow($applicable_indexes, $row_to_delete);

foreach ($index_ref_deletes as list($index_name, $index_key, $_)) {
unset($index_refs[$index_name][$index_key][$row_id]);
foreach ($index_ref_deletes as list($index_name, $index_keys, $store_as_unique)) {
$specific_index_refs = $index_refs[$index_name] ?? null;
if ($specific_index_refs is nonnull) {
self::removeFromIndexes(inout $specific_index_refs, $index_keys, $store_as_unique, $row_id);
$index_refs[$index_name] = $specific_index_refs;
}
}
}
}

// write it back to the database
$conn->getServer()->saveTable($database, $table_name, $remaining_rows, $unique_index_refs, $index_refs);
$conn->getServer()->saveTable($database, $table_name, $remaining_rows, $index_refs);
return $rows_affected;
}
}

0 comments on commit 6b6fd88

Please sign in to comment.