Commit 2dd2cae91b912dc1eab59d002bafe9d5fe7b437d

Authored by Andrii Shvaika
1 parent d83d9ec3

Bug Fix for DeviceSearch and Entity queries

... ... @@ -333,8 +333,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
333 333 if (pageLink.getPageSize() > 0) {
334 334 dataQuery = String.format("%s limit %s offset %s", dataQuery, pageLink.getPageSize(), startIndex);
335 335 }
336   -// log.error("QUERY: {}", dataQuery);
337   -// Arrays.asList(ctx.getParameterNames()).forEach(param -> log.error("QUERY PARAM: {}->{}", param, ctx.getValue(param)));
  336 + log.error("QUERY: {}", dataQuery);
  337 + Arrays.asList(ctx.getParameterNames()).forEach(param -> log.error("QUERY PARAM: {}->{}", param, ctx.getValue(param)));
338 338 List<Map<String, Object>> rows = jdbcTemplate.queryForList(dataQuery, ctx);
339 339 return EntityDataAdapter.createEntityData(pageLink, selectionMapping, rows, totalElements);
340 340 });
... ... @@ -432,7 +432,12 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
432 432 String lvlFilter = getLvlFilter(entityFilter.getMaxLevel());
433 433 String selectFields = "SELECT tenant_id, customer_id, id, created_time, type, name, label FROM " + entityType.name() + " WHERE id in ( SELECT entity_id";
434 434 String from = getQueryTemplate(entityFilter.getDirection());
435   - String whereFilter = " WHERE re.relation_type = :where_relation_type AND re.to_type = :where_entity_type";
  435 + String whereFilter = " WHERE";
  436 + if (!StringUtils.isEmpty(entityFilter.getRelationType())) {
  437 + ctx.addStringParameter("where_relation_type", entityFilter.getRelationType());
  438 + whereFilter += " re.relation_type = :where_relation_type AND";
  439 + }
  440 + whereFilter += " re.to_type = :where_entity_type";
436 441
437 442 from = String.format(from, lvlFilter, whereFilter);
438 443 String query = "( " + selectFields + from + ")";
... ... @@ -443,7 +448,6 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
443 448 query += " )";
444 449 ctx.addUuidParameter("relation_root_id", rootId.getId());
445 450 ctx.addStringParameter("relation_root_type", rootId.getEntityType().name());
446   - ctx.addStringParameter("where_relation_type", entityFilter.getRelationType());
447 451 ctx.addStringParameter("where_entity_type", entityType.name());
448 452 return query;
449 453 }
... ... @@ -465,36 +469,27 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
465 469
466 470 StringBuilder whereFilter;
467 471 if (entityFilter.getFilters() != null && !entityFilter.getFilters().isEmpty()) {
468   - whereFilter = new StringBuilder(" WHERE ");
  472 + whereFilter = new StringBuilder();
469 473 boolean first = true;
470 474 boolean single = entityFilter.getFilters().size() == 1;
471 475 int entityTypeFilterIdx = 0;
472 476 for (EntityTypeFilter etf : entityFilter.getFilters()) {
473   - if (first) {
474   - first = false;
475   - } else {
476   - whereFilter.append(" AND ");
477   - }
478   - String relationType = etf.getRelationType();
479   - if (!single) {
480   - whereFilter.append(" (");
481   - }
482   - List<String> whereEntityTypes = etf.getEntityTypes().stream().map(EntityType::name).collect(Collectors.toList());
483   - whereFilter
484   - .append(" re.relation_type = :where_relation_type").append(entityTypeFilterIdx);
485   - if (!whereEntityTypes.isEmpty()) {
486   - whereFilter.append(" and re.")
487   - .append(entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from")
488   - .append("_type in (:where_entity_types").append(entityTypeFilterIdx).append(")");
489   - }
490   - if (!single) {
491   - whereFilter.append(" )");
492   - }
493   - ctx.addStringParameter("where_relation_type" + entityTypeFilterIdx, relationType);
494   - if (!whereEntityTypes.isEmpty()) {
495   - ctx.addStringListParameter("where_entity_types" + entityTypeFilterIdx, whereEntityTypes);
  477 + String etfCondition = buildEtfCondition(ctx, etf, entityFilter.getDirection(), entityTypeFilterIdx++);
  478 + if (!etfCondition.isEmpty()) {
  479 + if (first) {
  480 + whereFilter.append(" WHERE ");
  481 + first = false;
  482 + } else {
  483 + whereFilter.append(" AND ");
  484 + }
  485 + if (!single) {
  486 + whereFilter.append(" (");
  487 + }
  488 + whereFilter.append(etfCondition);
  489 + if (!single) {
  490 + whereFilter.append(" )");
  491 + }
496 492 }
497   - entityTypeFilterIdx++;
498 493 }
499 494 } else {
500 495 whereFilter = new StringBuilder();
... ... @@ -503,6 +498,34 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
503 498 return "( " + selectFields + from + ")";
504 499 }
505 500
  501 + private String buildEtfCondition(QueryContext ctx, EntityTypeFilter etf, EntitySearchDirection direction, int entityTypeFilterIdx) {
  502 + StringBuilder whereFilter = new StringBuilder();
  503 + String relationType = etf.getRelationType();
  504 + List<EntityType> entityTypes = etf.getEntityTypes();
  505 + List<String> whereEntityTypes;
  506 + if (entityTypes == null || entityTypes.isEmpty()) {
  507 + whereEntityTypes = Collections.emptyList();
  508 + } else {
  509 + whereEntityTypes = etf.getEntityTypes().stream().map(EntityType::name).collect(Collectors.toList());
  510 + }
  511 + boolean hasRelationType = !StringUtils.isEmpty(relationType);
  512 + if (hasRelationType) {
  513 + ctx.addStringParameter("where_relation_type" + entityTypeFilterIdx, relationType);
  514 + whereFilter
  515 + .append("re.relation_type = :where_relation_type").append(entityTypeFilterIdx);
  516 + }
  517 + if (!whereEntityTypes.isEmpty()) {
  518 + if (hasRelationType) {
  519 + whereFilter.append(" and ");
  520 + }
  521 + whereFilter.append("re.")
  522 + .append(direction.equals(EntitySearchDirection.FROM) ? "to" : "from")
  523 + .append("_type in (:where_entity_types").append(entityTypeFilterIdx).append(")");
  524 + ctx.addStringListParameter("where_entity_types" + entityTypeFilterIdx, whereEntityTypes);
  525 + }
  526 + return whereFilter.toString();
  527 + }
  528 +
506 529 private String getLvlFilter(int maxLevel) {
507 530 return maxLevel > 0 ? ("and lvl <= " + (maxLevel - 1)) : "";
508 531 }
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.dao.sql.query;
17 17
  18 +import lombok.extern.slf4j.Slf4j;
18 19 import org.hibernate.type.PostgresUUIDType;
19 20 import org.springframework.jdbc.core.namedparam.SqlParameterSource;
20 21 import org.thingsboard.server.common.data.EntityType;
... ... @@ -27,6 +28,7 @@ import java.util.List;
27 28 import java.util.Map;
28 29 import java.util.UUID;
29 30
  31 +@Slf4j
30 32 public class QueryContext implements SqlParameterSource {
31 33 private static final PostgresUUIDType UUID_TYPE = new PostgresUUIDType();
32 34
... ... @@ -43,9 +45,12 @@ public class QueryContext implements SqlParameterSource {
43 45 void addParameter(String name, Object value, int type, String typeName) {
44 46 Parameter newParam = new Parameter(value, type, typeName);
45 47 Parameter oldParam = params.put(name, newParam);
46   - if (oldParam != null && !oldParam.value.equals(newParam.value)) {
  48 + if (oldParam != null && oldParam.value != null && !oldParam.value.equals(newParam.value)) {
47 49 throw new RuntimeException("Parameter with name: " + name + " was already registered!");
48 50 }
  51 + if(value == null){
  52 + log.warn("[{}][{}][{}] Trying to set null value", getTenantId(), getCustomerId(), name);
  53 + }
49 54 }
50 55
51 56 public void append(String s) {
... ...