Query conditions not working as expected in Database Manager

Wappler Version :
Operating System :
Server Model:
Database Type:
Hosting Type:

Expected behavior

What do you think should happen?

It's been a while since I've hand written MySQL queries, but in my experience with MySQL NOT should be right before LIKE in the WHERE clause when using NOT LIKE. Not sure if Wappler has a different way of doing it, but the value being queried should also have wildcards around it when using NOT LIKE (doesn't contain) or LIKE (contains) such as '%value%' or 'value%' etc. It's not throwing any errors so perhaps you can put NOT before the column then LIKE but whatever the case the query is failing and I suspect it has something to do with the wildcards or lack thereof?

Actual behavior

What actually happens?

It's putting NOT before the query column in the condition:

where (`notifications`.`user_id` = ? or `notifications`.`role_id` = ? or `notifications`.`role_id` = ?) and not `notifications`.`notification_read_by` like ?

And I'm not sure where/when Wappler adds or uses the wildcards '%value%' but if it's supposed to be there, they are not.

The query works until I add the final condition of 'AND doesn't contain' then it returns no results and it should return results because that column is NULL right now so it doesn't contain the value I'm testing against. I used "doesn't contain" and it generates this query:

Here is the generated query code:

{
        "name": "qNotifications",
        "module": "dbconnector",
        "action": "select",
        "options": {
          "connection": "db",
          "sql": {
            "type": "SELECT",
            "columns": [
              {
                "table": "notifications",
                "column": "notification_id"
              },
              {
                "table": "notifications",
                "column": "notification_title"
              },
              {
                "table": "notifications",
                "column": "notification_icon_class"
              },
              {
                "table": "notifications",
                "column": "notification"
              },
              {
                "table": "notifications",
                "column": "user_id"
              },
              {
                "table": "notifications",
                "column": "role_id"
              },
              {
                "table": "notifications",
                "column": "notification_created"
              },
              {
                "table": "notifications",
                "column": "notification_updated"
              },
              {
                "table": "notifications",
                "column": "notification_read_by"
              }
            ],
            "params": [
              {
                "operator": "equal",
                "type": "expression",
                "name": ":P1",
                "value": "{{qLoggedInUser.user_id}}",
                "test": ""
              },
              {
                "operator": "equal",
                "type": "expression",
                "name": ":P2",
                "value": "{{qLoggedInUser.role_id}}",
                "test": ""
              },
              {
                "operator": "not_ends_with",
                "type": "expression",
                "name": ":P3",
                "value": "{{','+qLoggedInUser.user_id+','}}",
                "test": ""
              }
            ],
            "table": {
              "name": "notifications"
            },
            "primary": "notification_id",
            "joins": [],
            "wheres": {
              "condition": "AND",
              "rules": [
                {
                  "condition": "OR",
                  "rules": [
                    {
                      "id": "notifications.user_id",
                      "field": "notifications.user_id",
                      "type": "double",
                      "operator": "equal",
                      "value": "{{qLoggedInUser.user_id}}",
                      "data": {
                        "table": "notifications",
                        "column": "user_id",
                        "type": "number",
                        "columnObj": {
                          "type": "integer",
                          "primary": false,
                          "nullable": true,
                          "name": "user_id"
                        }
                      },
                      "operation": "="
                    },
                    {
                      "id": "notifications.role_id",
                      "field": "notifications.role_id",
                      "type": "double",
                      "operator": "equal",
                      "value": "{{qLoggedInUser.role_id}}",
                      "data": {
                        "table": "notifications",
                        "column": "role_id",
                        "type": "number",
                        "columnObj": {
                          "type": "integer",
                          "primary": false,
                          "nullable": true,
                          "name": "role_id"
                        }
                      },
                      "operation": "="
                    },
                    {
                      "id": "notifications.role_id",
                      "field": "notifications.role_id",
                      "type": "double",
                      "operator": "equal",
                      "value": 4,
                      "data": {
                        "table": "notifications",
                        "column": "role_id",
                        "type": "number",
                        "columnObj": {
                          "type": "integer",
                          "primary": false,
                          "nullable": true,
                          "name": "role_id"
                        }
                      },
                      "operation": "="
                    }
                  ],
                  "conditional": null
                },
                {
                  "id": "notifications.notification_read_by",
                  "field": "notifications.notification_read_by",
                  "type": "string",
                  "operator": "not_ends_with",
                  "value": "{{','+qLoggedInUser.user_id+','}}",
                  "data": {
                    "table": "notifications",
                    "column": "notification_read_by",
                    "type": "text",
                    "columnObj": {
                      "type": "text",
                      "maxLength": 65535,
                      "primary": false,
                      "nullable": true,
                      "name": "notification_read_by"
                    }
                  },
                  "operation": "NOT LIKE"
                }
              ],
              "conditional": null,
              "valid": true
            },
            "orders": [
              {
                "table": "notifications",
                "column": "notification_created",
                "direction": "DESC",
                "recid": 1
              }
            ],
            "query": "select `notification_id`, `notification_title`, `notification_icon_class`, `notification`, `user_id`, `role_id`, `notification_created`, `notification_updated`, `notification_read_by` from `notifications` where (`notifications`.`user_id` = ? or `notifications`.`role_id` = ? or `notifications`.`role_id` = ?) and not `notifications`.`notification_read_by` like ? order by `notification_created` DESC"
          }
        },
        "output": true,
        "meta": [
          {
            "type": "number",
            "name": "notification_id"
          },
          {
            "type": "text",
            "name": "notification_title"
          },
          {
            "type": "text",
            "name": "notification_icon_class"
          },
          {
            "type": "text",
            "name": "notification"
          },
          {
            "type": "number",
            "name": "user_id"
          },
          {
            "type": "number",
            "name": "role_id"
          },
          {
            "type": "datetime",
            "name": "notification_created"
          },
          {
            "type": "datetime",
            "name": "notification_updated"
          },
          {
            "type": "text",
            "name": "notification_read_by"
          }
        ],
        "outputType": "array",
        "collapsed": true
      },

Here is a dump of the notifications table if needed for testing:
notifications.zip (1.5 KB)

How to reproduce

I tested it and was able to reproduce it by creating another query with 3 OR conditions and an AND doesn't contain condition. It put the NOT before the query column and I don't see any wildcards.

Unless I'm missing something simple, this query should return results.

Thanks in advance,
Twitch

Edit: Disregard this comment, I might've made a mistake

The SQL query you see is not real, it's a representation, since a certain Wappler update.

That being said, if you're noticing a bug, it's probably not related to the query you see

It's the same in the code view which I'm guessing is the real query?

"query": "select `notification_id`, `notification_title`, `notification_icon_class`, `notification`, `user_id`, `role_id`, `notification_created`, `notification_updated`, `notification_read_by` from `notifications` where (`notifications`.`user_id` = ? or `notifications`.`role_id` = ? or `notifications`.`role_id` = ?) and not `notifications`.`notification_read_by` like ? order by `notification_created` DESC"
          

Actually I might've made a mistake, disregard my previous comment

1 Like

Ok I've done some more testing. It's definitely not acting right.

Added to the query bit by bit to see when it starts to fail.

Here are the records and the values I'm querying against.

First I added the user_id={{qloggedInUser.user_id}} condition by itself:

And it properly returns both records that contain the logged in user id of 1
Screenshot 2025-06-19 at 11.01.26 AM

Then I add the OR role_id=4

It correctly returns 3 records, the two with the user id of 1 and the 1 record that has role_id of 4

Then I add the AND condition to filter out any of the records that the logged in user id has already marked as read. In this case I hardcoded the id of 1 for testing. I bookend the ids with commas so they can easily be filtered otherwise if you query 'doesn't contain' 1 it will also filter out all ids that contain a 1.

So this query should return two records the ones that don't have ,1, in the read by column but it doesn't return anything.

Screenshot 2025-06-19 at 11.09.41 AM

Perhaps it's something with the order Wappler is running the conditions? I've done a lot more complex queries than this in Wappler, so it's baffling me.

-Twitch

Interestingly enough, I ran the query in TablePlus and it also returns no results. What is going on with this query.... :thinking:

select `notification_id`, `notification_title`, `notification_icon_class`, `notification`, `user_id`, `role_id`, `notification_created`, `notification_updated`, `notification_read_by` from `notifications` where (`notifications`.`user_id` = 1 or `notifications`.`role_id` = 4) and `notifications`.`notification_read_by` not like '%,1,%' order by `notification_created` DESC```

Just curious and for diagnostic testing, what happens if you remove the , in your condition. I don't see anything wrong with your query but just trying to narrow it down.

Thanks for the reply @brad. I thought maybe the commas may be messing with it so I took them out but it still didn't work. I even tried changing the datatype of the notification_read_by field and no luck. It's really weird. Starting to wonder if it's a MySQL bug instead of a Wappler one.

Have you tried that last condition by itself without the grouped conditions?

I did in Wappler and as long as I added the wildcards manually around the condition expression, it worked and had the last condition by itself, it worked. I got rid of the read by field and am going to try a different way to mark them as read for now. Need to keep moving forward.

1 Like

I have found another example of a simple condition not working properly. I have a dropdown of choices, and in the query it uses if task_status equal to task_status, and if I try to search and match a value that has a space in it, it doesn't match but choices without spaces do.

In the header url it is encoded as such

task_status%3DIn%2BProgress

It's as though the Wappler query is not handling the %2B html entity properly.

Happens when the condition is "contains" as well. Watch, I it matches correctly until I add the space.

The backend conditions are set up correctly.

Really slowing this project down.

It's across all my queries, not just this tasks page. Not working if there is a space in the searched term.

What happens if you replace NULL with an empty string in the DB?

@Apple , I do appreciate the responses. I removed that field and am handing it a different way so I can't test that right way. However, the issue where searching for a string that contains a space, such as a task name in the tasks table or user name in the users table still remains. Won't match once I type the space as seen in that last video I posted.

I'm going to do some more testing to see what value is being sent to the query so I can look for characters that may be messing with it.

@patrick, I think I figured out the issue with searching for something with a space in the name. Still haven't figured out the other issue. The browser is sending a "+" for a space as it appears to have always done but Wappler is not handling it correctly.

Here is my site under development using the latest Wappler 7 where I try to search for a term with a space in the term with unexpected results.

here it is in the browser address field
Screenshot 2025-06-20 at 7.45.21 AM

here is the value that is sent to the query
Screenshot 2025-06-20 at 8.15.47 AM

No results because it's not replacing the + with a space

If I go to an older wappler app that I've had in production for a while and try a query with a space in it here I get the expected results because it does replace + correctly.

In the browser
Screenshot 2025-06-20 at 8.17.59 AM

value sent to the query correctly contains a space instead of +
Screenshot 2025-06-20 at 8.29.44 AM

Expected result returned:
Screenshot 2025-06-20 at 7.55.44 AM

If I go back to my query in the app under development and process the search term before sending to the query to replace + with space replace('+',' ') I get the expected results.
Screenshot 2025-06-20 at 8.12.19 AM

Screenshot 2025-06-20 at 7.56.16 AM

This explains the spaces in search terms issue, but not my other issue of using those OR conditions in conjunction with the AND condition I explained.

-Twitch

That's strange - I've always dealt with spaces like this from the first version of Wappler. Looking back at queries I created long ago, I used variables in search like:
{{$_GET.search.replace("+", " ").replace("%2B", " ")}}.
Perhaps it hasn't been necessary - and now it is again.

@TomD, That is interesting. I have never had to use replace in those queries till these last couple of versions. Actually not sure when it started.

Do you run NodeJS or PHP? The querystring should be parsed and decoded by default.

We have a urldecode formatter which you can use instead of the replace, but it should normally not be required.