mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-07-24 17:59:52 +00:00
GEN -19341 : Improvement - Avoid usage of CONCAT in WHERE clause (#19510)
* Improvement : Avoid usage of CONCAT in WHERE clause * fix tests * remove usage of @BindFqnConcat * remove usage of @BindFqnConcat * fix test * fix test
This commit is contained in:
parent
d386e9ca35
commit
82198f8126
@ -153,6 +153,7 @@ import org.openmetadata.service.resources.tags.TagLabelUtil;
|
||||
import org.openmetadata.service.util.EntityUtil;
|
||||
import org.openmetadata.service.util.FullyQualifiedName;
|
||||
import org.openmetadata.service.util.JsonUtils;
|
||||
import org.openmetadata.service.util.jdbi.BindConcat;
|
||||
import org.openmetadata.service.util.jdbi.BindFQN;
|
||||
import org.openmetadata.service.util.jdbi.BindListFQN;
|
||||
import org.openmetadata.service.util.jdbi.BindUUID;
|
||||
@ -747,20 +748,27 @@ public interface CollectionDAO {
|
||||
@SqlQuery(
|
||||
"SELECT id, extension, json "
|
||||
+ "FROM entity_extension "
|
||||
+ "WHERE id IN (<ids>) AND extension LIKE CONCAT(:extensionPrefix, '.%') "
|
||||
+ "WHERE id IN (<ids>) AND extension LIKE :extension "
|
||||
+ "ORDER BY id, extension")
|
||||
@RegisterRowMapper(ExtensionRecordWithIdMapper.class)
|
||||
List<ExtensionRecordWithId> getExtensionsBatch(
|
||||
@BindList("ids") List<String> ids, @Bind("extensionPrefix") String extensionPrefix);
|
||||
@BindList("ids") List<String> ids,
|
||||
@BindConcat(
|
||||
value = "extension",
|
||||
parts = {":extensionPrefix", ".%"})
|
||||
String extensionPrefix);
|
||||
|
||||
@SqlQuery(
|
||||
"SELECT id, extension, json, jsonschema "
|
||||
+ "FROM entity_extension "
|
||||
+ "WHERE extension LIKE CONCAT(:extensionPrefix, '%') "
|
||||
+ "WHERE extension LIKE :extension "
|
||||
+ "ORDER BY id, extension")
|
||||
@RegisterRowMapper(ExtensionWithIdAndSchemaRowMapper.class)
|
||||
List<ExtensionWithIdAndSchemaObject> getExtensionsByPrefixBatch(
|
||||
@Bind("extensionPrefix") String extensionPrefix);
|
||||
@BindConcat(
|
||||
value = "extension",
|
||||
parts = {":extensionPrefix", "%"})
|
||||
String extensionPrefix);
|
||||
|
||||
@Transaction
|
||||
@ConnectionAwareSqlBatch(
|
||||
@ -1492,16 +1500,25 @@ public interface CollectionDAO {
|
||||
@SqlQuery(
|
||||
"SELECT json FROM thread_entity <condition> "
|
||||
+ "AND hash_id in (SELECT fromFQNHash FROM field_relationship WHERE "
|
||||
+ "(:fqnPrefixHash IS NULL OR toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR toFQNHash=:fqnPrefixHash) AND fromType='THREAD' AND "
|
||||
+ "(:toType IS NULL OR toType LIKE CONCAT(:toType, '.%') OR toType=:toType) AND relation= :relation) "
|
||||
+ "(:fqnPrefixHash IS NULL OR toFQNHash LIKE :concatFqnPrefixHash OR toFQNHash=:fqnPrefixHash) AND fromType='THREAD' AND "
|
||||
+ "(:toType IS NULL OR toType LIKE :concatToType OR toType=:toType) AND relation= :relation) "
|
||||
+ "AND (:userName IS NULL OR MD5(id) in (SELECT toFQNHash FROM field_relationship WHERE "
|
||||
+ " ((fromType='user' AND fromFQNHash= :userName) OR"
|
||||
+ " (fromType='team' AND fromFQNHash IN (<teamNames>))) AND toType='THREAD' AND relation= :filterRelation) )"
|
||||
+ "<sortingOrder> "
|
||||
+ "LIMIT :limit")
|
||||
List<String> listThreadsByEntityLink(
|
||||
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
|
||||
@Bind("toType") String toType,
|
||||
@BindConcat(
|
||||
value = "concatFqnPrefixHash",
|
||||
original = "fqnPrefixHash",
|
||||
parts = {":fqnPrefixHash", ".%"},
|
||||
hash = true)
|
||||
String fqnPrefixHash,
|
||||
@BindConcat(
|
||||
value = "concatToType",
|
||||
original = "toType",
|
||||
parts = {":toType", ".%"})
|
||||
String toType,
|
||||
@Bind("limit") int limit,
|
||||
@Bind("relation") int relation,
|
||||
@BindFQN("userName") String userName,
|
||||
@ -1533,14 +1550,23 @@ public interface CollectionDAO {
|
||||
@SqlQuery(
|
||||
"SELECT count(id) FROM thread_entity <condition> "
|
||||
+ "AND hash_id in (SELECT fromFQNHash FROM field_relationship WHERE "
|
||||
+ "(:fqnPrefixHash IS NULL OR toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR toFQNHash=:fqnPrefixHash) AND fromType='THREAD' AND "
|
||||
+ "(:toType IS NULL OR toType LIKE CONCAT(:toType, '.%') OR toType=:toType) AND relation= :relation) "
|
||||
+ "(:fqnPrefixHash IS NULL OR toFQNHash LIKE :concatFqnPrefixHash OR toFQNHash=:fqnPrefixHash) AND fromType='THREAD' AND "
|
||||
+ "(:toType IS NULL OR toType LIKE :concatToType OR toType=:toType) AND relation= :relation) "
|
||||
+ "AND (:userName IS NULL OR id in (SELECT toFQNHash FROM field_relationship WHERE "
|
||||
+ " ((fromType='user' AND fromFQNHash= :userName) OR"
|
||||
+ " (fromType='team' AND fromFQNHash IN (<teamNames>))) AND toType='THREAD' AND relation= :filterRelation) )")
|
||||
int listCountThreadsByEntityLink(
|
||||
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
|
||||
@Bind("toType") String toType,
|
||||
@BindConcat(
|
||||
value = "concatFqnPrefixHash",
|
||||
original = "fqnPrefixHash",
|
||||
parts = {":fqnPrefixHash", ".%"},
|
||||
hash = true)
|
||||
String fqnPrefixHash,
|
||||
@BindConcat(
|
||||
value = "concatToType",
|
||||
original = "toType",
|
||||
parts = {":toType", ".%"})
|
||||
String toType,
|
||||
@Bind("relation") int relation,
|
||||
@Bind("userName") String userName,
|
||||
@BindList("teamNames") List<String> teamNames,
|
||||
@ -1562,9 +1588,9 @@ public interface CollectionDAO {
|
||||
+ " WHERE hash_id IN ( "
|
||||
+ " SELECT fromFQNHash FROM field_relationship "
|
||||
+ " WHERE "
|
||||
+ " (:fqnPrefixHash IS NULL OR toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR toFQNHash = :fqnPrefixHash) "
|
||||
+ " (:fqnPrefixHash IS NULL OR toFQNHash LIKE :concatFqnPrefixHash OR toFQNHash = :fqnPrefixHash) "
|
||||
+ " AND fromType = 'THREAD' "
|
||||
+ " AND (:toType IS NULL OR toType LIKE CONCAT(:toType, '.%') OR toType = :toType) "
|
||||
+ " AND (:toType IS NULL OR toType LIKE :concatToType OR toType = :toType) "
|
||||
+ " AND relation = 3 "
|
||||
+ " ) "
|
||||
+ " UNION "
|
||||
@ -1576,8 +1602,17 @@ public interface CollectionDAO {
|
||||
@RegisterRowMapper(ThreadCountFieldMapper.class)
|
||||
List<List<String>> listCountByEntityLink(
|
||||
@BindUUID("entityId") UUID entityId,
|
||||
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
|
||||
@Bind("toType") String toType);
|
||||
@BindConcat(
|
||||
value = "concatFqnPrefixHash",
|
||||
original = "fqnPrefixHash",
|
||||
parts = {":fqnPrefixHash", ".%"},
|
||||
hash = true)
|
||||
String fqnPrefixHash,
|
||||
@BindConcat(
|
||||
value = "concatToType",
|
||||
original = "toType",
|
||||
parts = {":toType", ".%"})
|
||||
String toType);
|
||||
|
||||
@ConnectionAwareSqlQuery(
|
||||
value =
|
||||
@ -1790,18 +1825,31 @@ public interface CollectionDAO {
|
||||
@SqlQuery(
|
||||
"SELECT json FROM thread_entity <condition> "
|
||||
+ "AND MD5(id) in (SELECT fromFQNHash FROM field_relationship WHERE "
|
||||
+ "(:fqnPrefixHash IS NULL OR toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR toFQNHash=:fqnPrefixHash) AND fromType='THREAD' AND "
|
||||
+ "((:toType1 IS NULL OR toType LIKE CONCAT(:toType1, '.%') OR toType=:toType1) OR "
|
||||
+ "(:toType2 IS NULL OR toType LIKE CONCAT(:toType2, '.%') OR toType=:toType2)) AND relation= :relation)"
|
||||
+ "(:fqnPrefixHash IS NULL OR toFQNHash LIKE :concatFqnPrefixHash OR toFQNHash=:fqnPrefixHash) AND fromType='THREAD' AND "
|
||||
+ "((:toType1 IS NULL OR toType LIKE :concatToType1 OR toType=:toType1) OR "
|
||||
+ "(:toType2 IS NULL OR toType LIKE :concatToType2 OR toType=:toType2)) AND relation= :relation)"
|
||||
+ "AND (:userName IS NULL OR MD5(id) in (SELECT toFQNHash FROM field_relationship WHERE "
|
||||
+ " ((fromType='user' AND fromFQNHash= :userName) OR"
|
||||
+ " (fromType='team' AND fromFQNHash IN (<teamNames>))) AND toType='THREAD' AND relation= :filterRelation) )"
|
||||
+ "<sortingOrder> "
|
||||
+ "LIMIT :limit")
|
||||
List<String> listThreadsByGlossaryAndTerms(
|
||||
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
|
||||
@Bind("toType1") String toType1,
|
||||
@Bind("toType2") String toType2,
|
||||
@BindConcat(
|
||||
value = "concatFqnPrefixHash",
|
||||
original = "fqnPrefixHash",
|
||||
parts = {":fqnPrefixHash", ".%"},
|
||||
hash = true)
|
||||
String fqnPrefixHash,
|
||||
@BindConcat(
|
||||
value = "concatToType1",
|
||||
original = "toType1",
|
||||
parts = {":toType1", ".%"})
|
||||
String toType1,
|
||||
@BindConcat(
|
||||
value = "concatToType2",
|
||||
original = "toType2",
|
||||
parts = {":toType2", ".%"})
|
||||
String toType2,
|
||||
@Bind("limit") int limit,
|
||||
@Bind("relation") int relation,
|
||||
@BindFQN("userName") String userName,
|
||||
@ -1833,9 +1881,9 @@ public interface CollectionDAO {
|
||||
+ " WHERE te.hash_id IN ( "
|
||||
+ " SELECT fr.fromFQNHash "
|
||||
+ " FROM field_relationship fr "
|
||||
+ " WHERE (:fqnPrefixHash IS NULL OR fr.toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR fr.toFQNHash = :fqnPrefixHash) "
|
||||
+ " WHERE (:fqnPrefixHash IS NULL OR fr.toFQNHash LIKE :concatFqnPrefixHash OR fr.toFQNHash = :fqnPrefixHash) "
|
||||
+ " AND fr.fromType = 'THREAD' "
|
||||
+ " AND (:toType1 IS NULL OR fr.toType LIKE CONCAT(:toType1, '.%') OR fr.toType = :toType1) "
|
||||
+ " AND (:toType1 IS NULL OR fr.toType LIKE :concatToType1 OR fr.toType = :toType1) "
|
||||
+ " AND fr.relation = 3 "
|
||||
+ " ) "
|
||||
+ " UNION "
|
||||
@ -1846,9 +1894,9 @@ public interface CollectionDAO {
|
||||
+ " SELECT fr.fromFQNHash "
|
||||
+ " FROM field_relationship fr "
|
||||
+ " JOIN thread_entity te2 ON te2.hash_id = fr.fromFQNHash WHERE fr.fromFQNHash = te.hash_id AND te2.type = 'Task' "
|
||||
+ " AND (:fqnPrefixHash IS NULL OR fr.toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR fr.toFQNHash = :fqnPrefixHash) "
|
||||
+ " AND (:fqnPrefixHash IS NULL OR fr.toFQNHash LIKE :concatFqnPrefixHash OR fr.toFQNHash = :fqnPrefixHash) "
|
||||
+ " AND fr.fromType = 'THREAD' "
|
||||
+ " AND (:toType2 IS NULL OR fr.toType LIKE CONCAT(:toType2, '.%') OR fr.toType = :toType2) "
|
||||
+ " AND (:toType2 IS NULL OR fr.toType LIKE :concatToType2 OR fr.toType = :toType2) "
|
||||
+ " AND fr.relation = 3 "
|
||||
+ " ) "
|
||||
+ ") AS combined_results WHERE combined_results.type is not NULL "
|
||||
@ -1856,9 +1904,22 @@ public interface CollectionDAO {
|
||||
@RegisterRowMapper(ThreadCountFieldMapper.class)
|
||||
List<List<String>> listCountThreadsByGlossaryAndTerms(
|
||||
@BindUUID("entityId") UUID entityId,
|
||||
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
|
||||
@Bind("toType1") String toType1,
|
||||
@Bind("toType2") String toType2);
|
||||
@BindConcat(
|
||||
value = "concatFqnPrefixHash",
|
||||
original = "fqnPrefixHash",
|
||||
parts = {":fqnPrefixHash", ".%"},
|
||||
hash = true)
|
||||
String fqnPrefixHash,
|
||||
@BindConcat(
|
||||
value = "concatToType1",
|
||||
original = "toType1",
|
||||
parts = {":toType1", ".%"})
|
||||
String toType1,
|
||||
@BindConcat(
|
||||
value = "concatToType2",
|
||||
original = "toType2",
|
||||
parts = {":toType2", ".%"})
|
||||
String toType2);
|
||||
|
||||
@SqlQuery("select id from thread_entity where entityId = :entityId")
|
||||
List<String> findByEntityId(@Bind("entityId") String entityId);
|
||||
@ -1963,11 +2024,15 @@ public interface CollectionDAO {
|
||||
|
||||
@SqlQuery(
|
||||
"SELECT fromFQN, toFQN, json FROM field_relationship WHERE "
|
||||
+ "fromFQNHash LIKE CONCAT(:fqnPrefixHash, '%') AND fromType = :fromType AND toType = :toType "
|
||||
+ "fromFQNHash LIKE :concatFqnPrefixHash AND fromType = :fromType AND toType = :toType "
|
||||
+ "AND relation = :relation")
|
||||
@RegisterRowMapper(ToFieldMapper.class)
|
||||
List<Triple<String, String, String>> listToByPrefix(
|
||||
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
|
||||
@BindConcat(
|
||||
value = "concatFqnPrefixHash",
|
||||
parts = {":fqnPrefixHash", "%"},
|
||||
hash = true)
|
||||
String fqnPrefixHash,
|
||||
@Bind("fromType") String fromType,
|
||||
@Bind("toType") String toType,
|
||||
@Bind("relation") int relation);
|
||||
@ -1993,13 +2058,17 @@ public interface CollectionDAO {
|
||||
|
||||
@SqlQuery(
|
||||
"SELECT fromFQN, toFQN, json FROM field_relationship WHERE "
|
||||
+ "fromFQNHash LIKE CONCAT(:fqnPrefixHash, '%') AND fromType = :type AND toType = :otherType AND relation = :relation "
|
||||
+ "fromFQNHash LIKE :concatFqnPrefixHash AND fromType = :type AND toType = :otherType AND relation = :relation "
|
||||
+ "UNION "
|
||||
+ "SELECT toFQN, fromFQN, json FROM field_relationship WHERE "
|
||||
+ "toFQNHash LIKE CONCAT(:fqnPrefixHash, '%') AND toType = :type AND fromType = :otherType AND relation = :relation")
|
||||
+ "toFQNHash LIKE :concatFqnPrefixHash AND toType = :type AND fromType = :otherType AND relation = :relation")
|
||||
@RegisterRowMapper(ToFieldMapper.class)
|
||||
List<Triple<String, String, String>> listBidirectionalByPrefix(
|
||||
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
|
||||
@BindConcat(
|
||||
value = "concatFqnPrefixHash",
|
||||
parts = {":fqnPrefixHash", "%"},
|
||||
hash = true)
|
||||
String fqnPrefixHash,
|
||||
@Bind("type") String type,
|
||||
@Bind("otherType") String otherType,
|
||||
@Bind("relation") int relation);
|
||||
@ -2491,12 +2560,12 @@ public interface CollectionDAO {
|
||||
String directChildrenOf = filter.getQueryParam("directChildrenOf");
|
||||
|
||||
if (!nullOrEmpty(directChildrenOf)) {
|
||||
filter.queryParams.put(
|
||||
"directChildrenOfHash", FullyQualifiedName.buildHash(directChildrenOf));
|
||||
condition =
|
||||
String.format(
|
||||
" %s AND fqnHash = CONCAT(:directChildrenOfHash, '.', MD5(CASE WHEN name LIKE '%%.%%' THEN CONCAT('\"', name, '\"') ELSE name END)) ",
|
||||
condition);
|
||||
String parentFqnHash = FullyQualifiedName.buildHash(directChildrenOf);
|
||||
filter.queryParams.put("fqnHashSingleLevel", parentFqnHash + ".%");
|
||||
filter.queryParams.put("fqnHashNestedLevel", parentFqnHash + ".%.%");
|
||||
|
||||
condition +=
|
||||
" AND fqnHash LIKE :fqnHashSingleLevel AND fqnHash NOT LIKE :fqnHashNestedLevel";
|
||||
}
|
||||
|
||||
return listCount(getTableName(), getNameHashColumn(), filter.getQueryParams(), condition);
|
||||
@ -2509,12 +2578,12 @@ public interface CollectionDAO {
|
||||
String directChildrenOf = filter.getQueryParam("directChildrenOf");
|
||||
|
||||
if (!nullOrEmpty(directChildrenOf)) {
|
||||
filter.queryParams.put(
|
||||
"directChildrenOfHash", FullyQualifiedName.buildHash(directChildrenOf));
|
||||
condition =
|
||||
String.format(
|
||||
" %s AND fqnHash = CONCAT(:directChildrenOfHash, '.', MD5(CASE WHEN name LIKE '%%.%%' THEN CONCAT('\"', name, '\"') ELSE name END)) ",
|
||||
condition);
|
||||
String parentFqnHash = FullyQualifiedName.buildHash(directChildrenOf);
|
||||
filter.queryParams.put("fqnHashSingleLevel", parentFqnHash + ".%");
|
||||
filter.queryParams.put("fqnHashNestedLevel", parentFqnHash + ".%.%");
|
||||
|
||||
condition +=
|
||||
" AND fqnHash LIKE :fqnHashSingleLevel AND fqnHash NOT LIKE :fqnHashNestedLevel";
|
||||
}
|
||||
|
||||
return listBefore(
|
||||
@ -2527,19 +2596,24 @@ public interface CollectionDAO {
|
||||
String directChildrenOf = filter.getQueryParam("directChildrenOf");
|
||||
|
||||
if (!nullOrEmpty(directChildrenOf)) {
|
||||
filter.queryParams.put(
|
||||
"directChildrenOfHash", FullyQualifiedName.buildHash(directChildrenOf));
|
||||
condition =
|
||||
String.format(
|
||||
" %s AND fqnHash = CONCAT(:directChildrenOfHash, '.', MD5(CASE WHEN name LIKE '%%.%%' THEN CONCAT('\"', name, '\"') ELSE name END)) ",
|
||||
condition);
|
||||
String parentFqnHash = FullyQualifiedName.buildHash(directChildrenOf);
|
||||
filter.queryParams.put("fqnHashSingleLevel", parentFqnHash + ".%");
|
||||
filter.queryParams.put("fqnHashNestedLevel", parentFqnHash + ".%.%");
|
||||
|
||||
condition +=
|
||||
" AND fqnHash LIKE :fqnHashSingleLevel AND fqnHash NOT LIKE :fqnHashNestedLevel";
|
||||
}
|
||||
return listAfter(
|
||||
getTableName(), filter.getQueryParams(), condition, limit, afterName, afterId);
|
||||
}
|
||||
|
||||
@SqlQuery("select json FROM glossary_term_entity where fqnhash LIKE CONCAT(:fqnhash, '.%')")
|
||||
List<String> getNestedTerms(@BindFQN("fqnhash") String fqnhash);
|
||||
@SqlQuery("select json FROM glossary_term_entity where fqnhash LIKE :concatFqnhash ")
|
||||
List<String> getNestedTerms(
|
||||
@BindConcat(
|
||||
value = "concatFqnhash",
|
||||
parts = {":fqnhash", ".%"},
|
||||
hash = true)
|
||||
String fqnhash);
|
||||
}
|
||||
|
||||
interface IngestionPipelineDAO extends EntityDAO<IngestionPipeline> {
|
||||
@ -3170,8 +3244,13 @@ public interface CollectionDAO {
|
||||
afterId);
|
||||
}
|
||||
|
||||
@SqlQuery("select json FROM tag where fqnhash LIKE CONCAT(:fqnhash, '.%')")
|
||||
List<String> getTagsStartingWithPrefix(@BindFQN("fqnhash") String fqnhash);
|
||||
@SqlQuery("select json FROM tag where fqnhash LIKE :concatFqnhash")
|
||||
List<String> getTagsStartingWithPrefix(
|
||||
@BindConcat(
|
||||
value = "concatFqnhash",
|
||||
parts = {":fqnhash", ".%"},
|
||||
hash = true)
|
||||
String fqnhash);
|
||||
}
|
||||
|
||||
@RegisterRowMapper(TagLabelMapper.class)
|
||||
@ -3200,10 +3279,11 @@ public interface CollectionDAO {
|
||||
|
||||
default Map<String, List<TagLabel>> getTagsByPrefix(
|
||||
String targetFQNPrefix, String postfix, boolean requiresFqnHash) {
|
||||
String fqnHash =
|
||||
String targetFQNPrefixHash =
|
||||
requiresFqnHash ? FullyQualifiedName.buildHash(targetFQNPrefix) : targetFQNPrefix;
|
||||
Map<String, List<TagLabel>> resultSet = new LinkedHashMap<>();
|
||||
List<Pair<String, TagLabel>> tags = getTagsInternalByPrefix(fqnHash, postfix);
|
||||
List<Pair<String, TagLabel>> tags =
|
||||
getTagsInternalByPrefix(new String[] {targetFQNPrefixHash, postfix});
|
||||
tags.forEach(
|
||||
pair -> {
|
||||
String targetHash = pair.getLeft();
|
||||
@ -3249,7 +3329,7 @@ public interface CollectionDAO {
|
||||
+ " ON ta.fqnHash = tu.tagFQNHash "
|
||||
+ " WHERE tu.source = 0 "
|
||||
+ ") AS combined_data "
|
||||
+ "WHERE combined_data.targetFQNHash LIKE CONCAT(:targetFQNHashPrefix, :postfix)",
|
||||
+ "WHERE combined_data.targetFQNHash LIKE :targetFQNHash",
|
||||
connectionType = MYSQL)
|
||||
@ConnectionAwareSqlQuery(
|
||||
value =
|
||||
@ -3265,11 +3345,14 @@ public interface CollectionDAO {
|
||||
+ " JOIN tag_usage AS tu ON ta.fqnHash = tu.tagFQNHash "
|
||||
+ " WHERE tu.source = 0 "
|
||||
+ ") AS combined_data "
|
||||
+ "WHERE combined_data.targetFQNHash LIKE CONCAT(:targetFQNHashPrefix, :postfix)",
|
||||
+ "WHERE combined_data.targetFQNHash LIKE :targetFQNHash",
|
||||
connectionType = POSTGRES)
|
||||
@RegisterRowMapper(TagLabelRowMapperWithTargetFqnHash.class)
|
||||
List<Pair<String, TagLabel>> getTagsInternalByPrefix(
|
||||
@Bind("targetFQNHashPrefix") String targetFQNHashPrefix, @Bind("postfix") String postfix);
|
||||
@BindConcat(
|
||||
value = "targetFQNHash",
|
||||
parts = {":targetFQNHashPrefix", ":postfix"})
|
||||
String... targetFQNHash);
|
||||
|
||||
@SqlQuery("SELECT * FROM tag_usage")
|
||||
@Deprecated(since = "Release 1.1")
|
||||
@ -3278,17 +3361,29 @@ public interface CollectionDAO {
|
||||
|
||||
@SqlQuery(
|
||||
"SELECT COUNT(*) FROM tag_usage "
|
||||
+ "WHERE (tagFQNHash LIKE CONCAT(:tagFqnHash, '.%') OR tagFQNHash = :tagFqnHash) "
|
||||
+ "WHERE (tagFQNHash LIKE :concatTagFQNHash OR tagFQNHash = :tagFqnHash) "
|
||||
+ "AND source = :source")
|
||||
int getTagCount(@Bind("source") int source, @BindFQN("tagFqnHash") String tagFqnHash);
|
||||
int getTagCount(
|
||||
@Bind("source") int source,
|
||||
@BindConcat(
|
||||
value = "concatTagFQNHash",
|
||||
original = "tagFqnHash",
|
||||
parts = {":tagFqnHash", ".%"},
|
||||
hash = true)
|
||||
String tagFqnHash);
|
||||
|
||||
@SqlUpdate("DELETE FROM tag_usage where targetFQNHash = :targetFQNHash")
|
||||
void deleteTagsByTarget(@BindFQN("targetFQNHash") String targetFQNHash);
|
||||
|
||||
@SqlUpdate(
|
||||
"DELETE FROM tag_usage where tagFQNHash = :tagFqnHash AND targetFQNHash LIKE CONCAT(:targetFQNHash, '%')")
|
||||
"DELETE FROM tag_usage where tagFQNHash = :tagFqnHash AND targetFQNHash LIKE :targetFQNHash")
|
||||
void deleteTagsByTagAndTargetEntity(
|
||||
@BindFQN("tagFqnHash") String tagFqnHash, @BindFQN("targetFQNHash") String targetFQNHash);
|
||||
@BindFQN("tagFqnHash") String tagFqnHash,
|
||||
@BindConcat(
|
||||
value = "targetFQNHash",
|
||||
parts = {":targetFQNHashPrefix", "%"},
|
||||
hash = true)
|
||||
String targetFQNHashPrefix);
|
||||
|
||||
@SqlUpdate("DELETE FROM tag_usage where tagFQNHash = :tagFQNHash AND source = :source")
|
||||
void deleteTagLabels(@Bind("source") int source, @BindFQN("tagFQNHash") String tagFQNHash);
|
||||
@ -3297,8 +3392,14 @@ public interface CollectionDAO {
|
||||
void deleteTagLabelsByFqn(@BindFQN("tagFQNHash") String tagFQNHash);
|
||||
|
||||
@SqlUpdate(
|
||||
"DELETE FROM tag_usage where targetFQNHash = :targetFQNHash OR targetFQNHash LIKE CONCAT(:targetFQNHash, '.%')")
|
||||
void deleteTagLabelsByTargetPrefix(@BindFQN("targetFQNHash") String targetFQNHash);
|
||||
"DELETE FROM tag_usage where targetFQNHash = :targetFQNHash OR targetFQNHash LIKE :concatTargetFQNHash")
|
||||
void deleteTagLabelsByTargetPrefix(
|
||||
@BindConcat(
|
||||
value = "concatTargetFQNHash",
|
||||
original = "targetFQNHash",
|
||||
parts = {":targetFQNHashPrefix", ".%"},
|
||||
hash = true)
|
||||
String targetFQNHashPrefix);
|
||||
|
||||
@Deprecated(since = "Release 1.1")
|
||||
@ConnectionAwareSqlUpdate(
|
||||
@ -3380,9 +3481,14 @@ public interface CollectionDAO {
|
||||
@RegisterRowMapper(TagLabelMapper.class)
|
||||
List<String> getTargetFQNHashForTag(@BindFQN("tagFQNHash") String tagFQNHash);
|
||||
|
||||
@SqlQuery("select targetFQNHash FROM tag_usage where tagFQNHash LIKE CONCAT(:tagFQNHash, '.%')")
|
||||
@SqlQuery("select targetFQNHash FROM tag_usage where tagFQNHash LIKE :tagFQNHash")
|
||||
@RegisterRowMapper(TagLabelMapper.class)
|
||||
List<String> getTargetFQNHashForTagPrefix(@BindFQN("tagFQNHash") String tagFQNHash);
|
||||
List<String> getTargetFQNHashForTagPrefix(
|
||||
@BindConcat(
|
||||
value = "tagFQNHash",
|
||||
parts = {":tagFQNHashPrefix", ".%"},
|
||||
hash = true)
|
||||
String tagFQNHashPrefix);
|
||||
|
||||
class TagLabelMapper implements RowMapper<TagLabel> {
|
||||
@Override
|
||||
@ -5586,8 +5692,8 @@ public interface CollectionDAO {
|
||||
if (fqnPrefix != null) {
|
||||
String fqnPrefixHash = FullyQualifiedName.buildHash(fqnPrefix);
|
||||
filter.queryParams.put("fqnPrefixHash", fqnPrefixHash);
|
||||
String fqnCond =
|
||||
" AND (fqnHash LIKE CONCAT(:fqnPrefixHash, '.%') OR fqnHash=:fqnPrefixHash)";
|
||||
filter.queryParams.put("concatFqnPrefixHash", fqnPrefixHash + ".%");
|
||||
String fqnCond = " AND (fqnHash LIKE :concatFqnPrefixHash OR fqnHash=:fqnPrefixHash)";
|
||||
mysqlCondition.append(fqnCond);
|
||||
psqlCondition.append(fqnCond);
|
||||
}
|
||||
@ -5625,8 +5731,8 @@ public interface CollectionDAO {
|
||||
if (fqnPrefix != null) {
|
||||
String fqnPrefixHash = FullyQualifiedName.buildHash(fqnPrefix);
|
||||
filter.queryParams.put("fqnPrefixHash", fqnPrefixHash);
|
||||
String fqnCond =
|
||||
" AND (fqnHash LIKE CONCAT(:fqnPrefixHash, '.%') OR fqnHash=:fqnPrefixHash)";
|
||||
filter.queryParams.put("concatFqnPrefixHash", fqnPrefixHash + ".%");
|
||||
String fqnCond = " AND (fqnHash LIKE :concatFqnPrefixHash OR fqnHash=:fqnPrefixHash)";
|
||||
mysqlCondition.append(fqnCond);
|
||||
psqlCondition.append(fqnCond);
|
||||
}
|
||||
@ -5663,8 +5769,8 @@ public interface CollectionDAO {
|
||||
if (fqnPrefix != null) {
|
||||
String fqnPrefixHash = FullyQualifiedName.buildHash(fqnPrefix);
|
||||
filter.queryParams.put("fqnPrefixHash", fqnPrefixHash);
|
||||
String fqnCond =
|
||||
" AND (fqnHash LIKE CONCAT(:fqnPrefixHash, '.%') OR fqnHash=:fqnPrefixHash)";
|
||||
filter.queryParams.put("concatFqnPrefixHash", fqnPrefixHash + ".%");
|
||||
String fqnCond = " AND (fqnHash LIKE :concatFqnPrefixHash OR fqnHash=:fqnPrefixHash)";
|
||||
mysqlCondition.append(fqnCond);
|
||||
psqlCondition.append(fqnCond);
|
||||
}
|
||||
|
@ -0,0 +1,80 @@
|
||||
package org.openmetadata.service.util.jdbi;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.lang.reflect.Type;
|
||||
import org.jdbi.v3.sqlobject.customizer.SqlStatementCustomizerFactory;
|
||||
import org.jdbi.v3.sqlobject.customizer.SqlStatementCustomizingAnnotation;
|
||||
import org.jdbi.v3.sqlobject.customizer.SqlStatementParameterCustomizer;
|
||||
import org.openmetadata.service.util.FullyQualifiedName;
|
||||
|
||||
/** Concatenate parts of a string to bind as a parameter, and avoid usage of CONCAT() in where clause */
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PARAMETER})
|
||||
@SqlStatementCustomizingAnnotation(BindConcat.Factory.class)
|
||||
public @interface BindConcat {
|
||||
String value(); // Name of the concatenated parameter to bind
|
||||
|
||||
String original() default
|
||||
""; // Optional: Use when both the original and concatenated values are needed
|
||||
|
||||
String[] parts() default {}; // Parts to concatenate (placeholders or static values)
|
||||
|
||||
boolean hash() default false; // Optional: Apply FullyQualifiedName.buildHash if true
|
||||
|
||||
class Factory implements SqlStatementCustomizerFactory {
|
||||
|
||||
@Override
|
||||
public SqlStatementParameterCustomizer createForParameter(
|
||||
Annotation annotation,
|
||||
Class<?> sqlObjectType,
|
||||
Method method,
|
||||
Parameter param,
|
||||
int index,
|
||||
Type type) {
|
||||
BindConcat bind = (BindConcat) annotation;
|
||||
|
||||
return (stmt, arg) -> {
|
||||
String[] partValues =
|
||||
(arg instanceof String[]) ? (String[]) arg : new String[] {String.valueOf(arg)};
|
||||
StringBuilder concatenatedResult = new StringBuilder();
|
||||
boolean containsNull = false;
|
||||
|
||||
for (int i = 0; i < bind.parts().length; i++) {
|
||||
String part = bind.parts()[i];
|
||||
if (part.startsWith(":")) { // Dynamic value in argument list to replace placeholder
|
||||
if (i >= partValues.length)
|
||||
throw new IllegalArgumentException(
|
||||
"Not enough values for placeholders in @BindConcat. Expected at least "
|
||||
+ (i + 1)
|
||||
+ " but got "
|
||||
+ partValues.length);
|
||||
String dynamicValue = partValues[i];
|
||||
if (dynamicValue == null) {
|
||||
containsNull = true;
|
||||
break;
|
||||
}
|
||||
concatenatedResult.append(
|
||||
bind.hash() ? FullyQualifiedName.buildHash(dynamicValue) : dynamicValue);
|
||||
} else { // Static part of the string, defined directly in the annotation
|
||||
concatenatedResult.append(part);
|
||||
}
|
||||
}
|
||||
|
||||
String finalValue = containsNull ? null : concatenatedResult.toString();
|
||||
stmt.bind(bind.value(), finalValue);
|
||||
if (!bind.original().isEmpty() && partValues.length > 0) {
|
||||
String originalValue = partValues[0];
|
||||
stmt.bind(
|
||||
bind.original(),
|
||||
bind.hash() ? FullyQualifiedName.buildHash(originalValue) : originalValue);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user