Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 152 additions & 35 deletions src/Glpi/Search/Provider/SQLProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,15 @@ public static function getSelectCriteria(string $itemtype, int $ID, bool $meta =
if (isset($opt["datatype"])) {
switch ($opt["datatype"]) {
case "count":
if ($opt["use_join_subquery"] ?? false) {
return array_merge([
QueryFunction::ifnull(
expression: new QueryExpression($DB::quoteName("{$table}{$addtable}.counter")),
value: new QueryExpression($DB::quoteValue('0')),
alias: $NAME,
),
], $ADDITONALFIELDS);
}
return array_merge([
QueryFunction::count(
expression: "$table$addtable.$field",
Expand Down Expand Up @@ -2716,7 +2725,8 @@ public static function getLeftJoinCriteria(
bool $meta = false,
string $meta_type = '',
array $joinparams = [],
string $field = ''
string $field = '',
bool $use_join_subquery = false
): array {
/** @var DBmysql $DB */
global $DB;
Expand Down Expand Up @@ -2966,18 +2976,44 @@ public static function getLeftJoinCriteria(
case 'child':
$linkfield = $joinparams['linkfield'] ?? getForeignKeyFieldForTable($cleanrt);

// Child join
$child_join = [
'LEFT JOIN' => [
"$new_table$AS" => [
'ON' => [
$rt => 'id',
$nt => $linkfield,
if ($use_join_subquery) {
$subquery = new QuerySubQuery(
[
'SELECT' => [
$linkfield,
new QueryExpression("COUNT(*)", "counter"),
],
'FROM' => $new_table,
'GROUPBY' => $linkfield,
],
],
];
$append_join_criteria($child_join['LEFT JOIN']["$new_table$AS"]['ON'], $add_criteria);
$nt
);

$child_join = [
'LEFT JOIN' => [
[
'TABLE' => $subquery,
'FKEY' => [
$rt => 'id',
$nt => $linkfield,
],
],
],
];
} else {
// Child join
$child_join = [
'LEFT JOIN' => [
"$new_table$AS" => [
'ON' => [
$rt => 'id',
$nt => $linkfield,
],
],
],
];
$append_join_criteria($child_join['LEFT JOIN']["$new_table$AS"]['ON'], $add_criteria);
}
$specific_leftjoin_criteria = array_merge_recursive($specific_leftjoin_criteria, $child_join);
break;

Expand Down Expand Up @@ -3057,22 +3093,64 @@ public static function getLeftJoinCriteria(
}

// Itemtype join
$itemtype_join = [
'LEFT JOIN' => [
"$new_table$AS" => [
'ON' => [
$rt => 'id',
$nt => "{$addmain}{$items_id_column}",
[
'AND' => [
"$nt.{$addmain}{$itemtype_column}" => $used_itemtype,
if ($use_join_subquery) {
$leftjoin = $before_criteria;
$leftjoin['LEFT JOIN']["$new_table$AS"] = [
'ON' => [
$rt => 'id',
$nt => "{$addmain}{$items_id_column}",
[
'AND' => [
"$nt.{$addmain}{$itemtype_column}" => $used_itemtype,
],
],
],
];
$leftjoin['INNER JOIN'] = $leftjoin['LEFT JOIN'];
unset($leftjoin['LEFT JOIN']);
$subquery = [
'SELECT' => [
"$ref_table.id",
new QueryExpression("COUNT(DISTINCT $nt.id)", "counter"),
],
'FROM' => $ref_table,
'GROUPBY' => "$ref_table.id",
] + $leftjoin;
$subtable = new QuerySubQuery(
$subquery,
$nt
);

$itemtype_join = [
'LEFT JOIN' => [
[
'TABLE' => $subtable,
'FKEY' => [
$ref_table => 'id',
$nt => 'id',
],
],
],
];
$before_criteria = [];
} else {
$itemtype_join = [
'LEFT JOIN' => [
"$new_table$AS" => [
'ON' => [
$rt => 'id',
$nt => "{$addmain}{$items_id_column}",
[
'AND' => [
"$nt.{$addmain}{$itemtype_column}" => $used_itemtype,
],
],
],
],
],
],
];
$append_join_criteria($itemtype_join['LEFT JOIN']["$new_table$AS"]['ON'], $add_criteria);
];
$append_join_criteria($itemtype_join['LEFT JOIN']["$new_table$AS"]['ON'], $add_criteria);
}
$specific_leftjoin_criteria = array_merge_recursive($specific_leftjoin_criteria, $itemtype_join);
break;

Expand Down Expand Up @@ -3142,18 +3220,55 @@ public static function getLeftJoinCriteria(
break;

default:
// Standard join
$standard_join = [
'LEFT JOIN' => [
"$new_table$AS" => [
'ON' => [
$rt => $linkfield,
$nt => 'id',
if ($use_join_subquery) {
$leftjoin = $before_criteria;
$leftjoin['LEFT JOIN']["$new_table$AS"] = [
'ON' => [
$rt => $linkfield,
$nt => 'id',
],
];
$leftjoin['INNER JOIN'] = $leftjoin['LEFT JOIN'];
unset($leftjoin['LEFT JOIN']);
$subquery = [
'SELECT' => [
"$ref_table.id",
new QueryExpression("COUNT(DISTINCT $nt.id)", "counter"),
],
'FROM' => $ref_table,
'GROUPBY' => "$ref_table.id",
] + $leftjoin;
$subtable = new QuerySubQuery(
$subquery,
$nt
);

$standard_join = [
'LEFT JOIN' => [
[
'TABLE' => $subtable,
'FKEY' => [
$ref_table => 'id',
$nt => 'id',
],
],
],
],
];
$append_join_criteria($standard_join['LEFT JOIN']["$new_table$AS"]['ON'], $add_criteria);
];
$before_criteria = [];
} else {
// Standard join
$standard_join = [
'LEFT JOIN' => [
"$new_table$AS" => [
'ON' => [
$rt => $linkfield,
$nt => 'id',
],
],
],
];
$append_join_criteria($standard_join['LEFT JOIN']["$new_table$AS"]['ON'], $add_criteria);
}
$specific_leftjoin_criteria = array_merge_recursive($specific_leftjoin_criteria, $standard_join);
$transitemtype = getItemTypeForTable($new_table);
if (Session::haveTranslations($transitemtype, $field)) {
Expand Down Expand Up @@ -4185,7 +4300,8 @@ public static function constructSQL(array &$data)
false,
'',
$searchopt[$val]["joinparams"],
$searchopt[$val]["field"]
$searchopt[$val]["field"],
($searchopt[$val]['use_join_subquery'] ?? false)
);
}
}
Expand Down Expand Up @@ -4894,7 +5010,8 @@ public static function constructAdditionalSqlForMetacriteria(
true,
$m_itemtype,
$sopt["joinparams"],
$sopt["field"]
$sopt["field"],
$sopt['use_join_subquery'] ?? false
);
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ public static function addDefaultJoin($itemtype, $ref_table, array &$already_lin
* @param string $meta_type Meta item type
* @param array $joinparams Array join parameters (condition / joinbefore...)
* @param string $field Field to display (needed for translation join) (default '')
* @param bool $use_join_subquery Use a subquery for the join (default false)
*
* @return string Left join string
**/
Expand All @@ -713,7 +714,8 @@ public static function addLeftJoin(
$meta = false,
$meta_type = '',
$joinparams = [],
$field = ''
$field = '',
$use_join_subquery = false
) {
/** @var DBmysql $DB */
global $DB;
Expand All @@ -726,7 +728,8 @@ public static function addLeftJoin(
(bool) $meta,
(string) $meta_type,
$joinparams,
$field
$field,
$use_join_subquery
);
$iterator = new DBmysqlIterator($DB);
$iterator->buildQuery([
Expand Down
3 changes: 3 additions & 0 deletions src/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -3550,6 +3550,7 @@ public function rawSearchOptions()
'forcegroupby' => true,
'usehaving' => true,
'datatype' => 'count',
'use_join_subquery' => true,
'massiveaction' => false,
'joinparams' => [
'beforejoin' => [
Expand All @@ -3570,6 +3571,7 @@ public function rawSearchOptions()
'forcegroupby' => true,
'usehaving' => true,
'datatype' => 'count',
'use_join_subquery' => true,
'massiveaction' => false,
'joinparams' => [
'jointype' => 'child',
Expand All @@ -3585,6 +3587,7 @@ public function rawSearchOptions()
'forcegroupby' => true,
'usehaving' => true,
'datatype' => 'count',
'use_join_subquery' => true,
'massiveaction' => false,
'joinparams' => [
'beforejoin' => [
Expand Down