Query builder fix root OR with more than one rule (#8457)

pushed the first recursion loop down, makes the code cleaner.
This commit is contained in:
Tony Murray
2018-03-23 09:39:13 -05:00
committed by Neil Lathwood
parent 0c0a70cc39
commit 333efe1402
2 changed files with 21 additions and 12 deletions

View File

@@ -231,21 +231,18 @@ class QueryBuilderParser implements \JsonSerializable
return null;
}
$result = [];
foreach ($this->builder['rules'] as $rule) {
if (array_key_exists('condition', $rule)) {
$result[] = $this->parseGroup($rule, $expand);
} else {
$result[] = $this->parseRule($rule, $expand);
}
}
$sql = '';
$wrap = false;
if ($expand) {
$sql = 'SELECT * FROM ' . implode(',', $this->getTables());
$sql .= ' WHERE ' . $this->generateGlue() . ' AND ';
// only wrap in ( ) if the condition is OR and there is more than one rule
$wrap = $this->builder['condition'] == 'OR' && count($this->builder['rules']) > 1;
}
return $sql . implode(" {$this->builder['condition']} ", $result);
return $sql . $this->parseGroup($this->builder, $expand, $wrap);
}
/**
@@ -253,9 +250,10 @@ class QueryBuilderParser implements \JsonSerializable
*
* @param $rule
* @param bool $expand Expand macros?
* @param bool $wrap Wrap in parenthesis
* @return string
*/
private function parseGroup($rule, $expand = false)
private function parseGroup($rule, $expand = false, $wrap = true)
{
$group_rules = [];
@@ -268,7 +266,12 @@ class QueryBuilderParser implements \JsonSerializable
}
$sql = implode(" {$rule['condition']} ", $group_rules);
return "($sql)";
if ($wrap) {
return "($sql)";
} else {
return "$sql";
}
}
/**

View File

@@ -106,5 +106,11 @@
{"condition":"AND","rules":[{"id":"bills.bill_name","field":"bills.bill_name","type":"string","input":"text","operator":"equal","value":"Neil's Bill"}],"valid":true},
"bills.bill_name = \"Neil's Bill\"",
"SELECT * FROM devices,ports,bill_ports,bills WHERE (devices.device_id = ? AND devices.device_id = ports.device_id AND ports.port_id = bill_ports.port_id AND bill_ports.bill_id = bills.bill_id) AND bills.bill_name = \"Neil's Bill\""
],
[
"%ports.ifOutErrors_rate >= \"100\" || %ports.ifInErrors_rate >= \"100\"",
{"condition":"OR","rules":[{"id":"ports.ifOutErrors_rate","field":"ports.ifOutErrors_rate","type":"integer","input":"text","operator":"greater_or_equal","value":"100"},{"id":"ports.ifInErrors_rate","field":"ports.ifInErrors_rate","type":"integer","input":"text","operator":"greater_or_equal","value":"100"}],"valid":true},
"ports.ifOutErrors_rate >= 100 OR ports.ifInErrors_rate >= 100",
"SELECT * FROM devices,ports WHERE (devices.device_id = ? AND devices.device_id = ports.device_id) AND (ports.ifOutErrors_rate >= 100 OR ports.ifInErrors_rate >= 100)"
]
]