diff --git a/app/src/androidTest/java/com/orgzly/android/query/QueryTest.kt b/app/src/androidTest/java/com/orgzly/android/query/QueryTest.kt index 8f9fbfbd6..0f85baf78 100644 --- a/app/src/androidTest/java/com/orgzly/android/query/QueryTest.kt +++ b/app/src/androidTest/java/com/orgzly/android/query/QueryTest.kt @@ -163,6 +163,12 @@ class QueryTest(private val param: Parameter) : OrgzlyTest() { expectedSqlSelection = "((COALESCE(tags, '') LIKE ? OR COALESCE(inherited_tags, '') LIKE ?))", expectedSelectionArgs = listOf("%tag%", "%tag%") ), + Parameter( + queryString = ".tn.tag", + expectedQueryString = ".tn.tag", + expectedSqlSelection = "(NOT((COALESCE(tags, '') LIKE ?)))", + expectedSelectionArgs = listOf("%tag%") + ), Parameter( queryString = "i.todo (b.\"book(1) name\" or b.book2)", expectedQueryString = "i.todo (b.\"book(1) name\" or b.book2)", diff --git a/app/src/main/java/com/orgzly/android/query/Condition.kt b/app/src/main/java/com/orgzly/android/query/Condition.kt index 7c74a55f9..a0c38657c 100644 --- a/app/src/main/java/com/orgzly/android/query/Condition.kt +++ b/app/src/main/java/com/orgzly/android/query/Condition.kt @@ -14,7 +14,7 @@ sealed class Condition { data class HasSetPriority(val priority: String, val not: Boolean = false) : Condition() data class HasTag(val tag: String, val not: Boolean = false) : Condition() - data class HasOwnTag(val tag: String) : Condition() + data class HasOwnTag(val tag: String, val not: Boolean = false) : Condition() data class Event(val interval: QueryInterval, val relation: Relation) : Condition() data class Scheduled(val interval: QueryInterval, val relation: Relation) : Condition() diff --git a/app/src/main/java/com/orgzly/android/query/sql/SqliteQueryBuilder.kt b/app/src/main/java/com/orgzly/android/query/sql/SqliteQueryBuilder.kt index 5a800f39d..6d39450e7 100644 --- a/app/src/main/java/com/orgzly/android/query/sql/SqliteQueryBuilder.kt +++ b/app/src/main/java/com/orgzly/android/query/sql/SqliteQueryBuilder.kt @@ -226,7 +226,7 @@ class SqliteQueryBuilder(val context: Context) { is Condition.HasOwnTag -> { arguments.add("%${expr.tag}%") - "tags LIKE ?" + not(expr.not, "(COALESCE(tags, '') LIKE ?)") } is Condition.Event -> { diff --git a/app/src/main/java/com/orgzly/android/query/user/BasicQueryParser.kt b/app/src/main/java/com/orgzly/android/query/user/BasicQueryParser.kt index 5afc7ff3c..e3ec23fca 100644 --- a/app/src/main/java/com/orgzly/android/query/user/BasicQueryParser.kt +++ b/app/src/main/java/com/orgzly/android/query/user/BasicQueryParser.kt @@ -35,8 +35,8 @@ open class BasicQueryParser : QueryParser() { Condition.HasTag(unQuote(match.groupValues[2]), match.groupValues[1].isNotEmpty()) }, - ConditionMatch("""^own-tag:(.+)""") { match -> - Condition.HasOwnTag(unQuote(match.groupValues[1])) + ConditionMatch("""^(-)?own-tag:(.+)""") { match -> + Condition.HasOwnTag(unQuote(match.groupValues[2]), match.groupValues[1].isNotEmpty()) }, ConditionMatch("""^(scheduled|deadline|closed|created):(?:(!=|<|<=|>|>=))?(.+)""") { match -> diff --git a/app/src/main/java/com/orgzly/android/query/user/DottedQueryBuilder.kt b/app/src/main/java/com/orgzly/android/query/user/DottedQueryBuilder.kt index f2c18a56f..9fa347a17 100644 --- a/app/src/main/java/com/orgzly/android/query/user/DottedQueryBuilder.kt +++ b/app/src/main/java/com/orgzly/android/query/user/DottedQueryBuilder.kt @@ -43,7 +43,7 @@ open class DottedQueryBuilder { is Condition.HasSetPriority -> "${dot(expr.not)}ps.${expr.priority}" is Condition.HasTag -> "${dot(expr.not)}t.${expr.tag}" - is Condition.HasOwnTag -> "tn.${expr.tag}" + is Condition.HasOwnTag -> "${dot(expr.not)}tn.${expr.tag}" is Condition.Event -> { val rel = expr.relation.toString().toLowerCase() diff --git a/app/src/main/java/com/orgzly/android/query/user/DottedQueryParser.kt b/app/src/main/java/com/orgzly/android/query/user/DottedQueryParser.kt index 6b781bac0..90f1f85e7 100644 --- a/app/src/main/java/com/orgzly/android/query/user/DottedQueryParser.kt +++ b/app/src/main/java/com/orgzly/android/query/user/DottedQueryParser.kt @@ -36,8 +36,8 @@ open class DottedQueryParser : QueryParser() { Condition.HasTag(unQuote(match.groupValues[2]), match.groupValues[1].isNotEmpty()) }, - ConditionMatch("""^tn\.(.+)""") { match -> - Condition.HasOwnTag(unQuote(match.groupValues[1])) + ConditionMatch("""^(\.)?tn\.(.+)""") { match -> + Condition.HasOwnTag(unQuote(match.groupValues[2]), match.groupValues[1].isNotEmpty()) }, ConditionMatch("""^(e|s|d|c|cr)(?:\.(eq|ne|lt|le|gt|ge))?\.(.+)""") { match ->