From a2bacabca0a98503858921a0c8668720d2545dbf Mon Sep 17 00:00:00 2001 From: Benn Oshrin Date: Sun, 19 Sep 2021 09:55:58 -0400 Subject: [PATCH] Create case insensitive indexes for case insensitive attributes (CO-2211) --- app/src/Lib/Match/MatchgridBuilder.php | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/app/src/Lib/Match/MatchgridBuilder.php b/app/src/Lib/Match/MatchgridBuilder.php index 4427ed239..3fad3c87e 100644 --- a/app/src/Lib/Match/MatchgridBuilder.php +++ b/app/src/Lib/Match/MatchgridBuilder.php @@ -103,6 +103,9 @@ protected function configToSchema($dbc, \Cake\Datasource\EntityInterface $Matchg $table->setPrimaryKey(["id"]); + // Track which attributes need case insensitive indexes + $ciAttrs = []; + if($indexes) { // Since index names need to be unique across the schema, we'll use the // matchgrid ID to make the names unique. @@ -124,7 +127,13 @@ protected function configToSchema($dbc, \Cake\Datasource\EntityInterface $Matchg // Add in indexes for configured fields foreach($attributes as $attr) { // We use the Entity ID to provide some level of reproducibility - $table->addIndex([$attr->name], 'matchgrid_' . $Matchgrid->id . '_attr_id'.$attr->id, $flags, $options); + $indexName = 'matchgrid_' . $Matchgrid->id . '_attr_id' . $attr->id; + + $table->addIndex([$attr->name], $indexName, $flags, $options); + + if(!$attr->case_sensitive) { + $ciAttrs[$indexName] = $attr->name; + } } } @@ -151,10 +160,23 @@ protected function configToSchema($dbc, \Cake\Datasource\EntityInterface $Matchg // needs to be fixed. foreach($diffSql as $sql) { + $matches = false; if(preg_match("/^CREATE INDEX .* \(resolution_time\)$/", $sql)) { // We need the resolution_time index to sort NULLS FIRST, and this is // currently the least painful way to do it $sql = rtrim($sql, ")") . " NULLS FIRST)"; + } elseif(preg_match("/^CREATE INDEX (\w+) ON .*/", $sql, $matches)) { + $attr = $ciAttrs[ $matches[1] ]; + + // Not ideal to hardcode SQL, but this should be pretty portable. + // Note the validation rule for table_name and attr is pretty restrictive, + // so we don't need to SQL escape them. Similarly, we create the index + // name above. + + // We use IF NOT EXISTS to avoid errors on rebuilding the matchgrid, + // however a better long term solution would be to add native support to + // DBAL for expression in index creation (CO-2217). + $sql = "CREATE INDEX IF NOT EXISTS " . $matches[1] . " ON " . $Matchgrid->prefixed_table_name . " (LOWER(" . $attr . "))"; } $stmt = $dbc->query($sql);