Skip to content

Allow AND/OR in WHERE clause of safe_upsert (+ useless spaces deleted)#722

Closed
NicolasGraph wants to merge 1 commit intotextpattern:masterfrom
NicolasGraph:master
Closed

Allow AND/OR in WHERE clause of safe_upsert (+ useless spaces deleted)#722
NicolasGraph wants to merge 1 commit intotextpattern:masterfrom
NicolasGraph:master

Conversation

@NicolasGraph
Copy link
Copy Markdown

@NicolasGraph NicolasGraph commented Jul 7, 2016

As said here, the following code does not work.

safe_upsert(
    'txp_lang', 
    'data = "My data", event = "public"',
    'name = "my_data" AND lang = "en-gb"'
)

The problem is that on INSERT, the WHERE clause is simply added to the set clause and throw that:

[SQL: INSERT INTO txp_lang SET name = 'my_data' AND lang = 'en-gb', data = 'My data', event = 'public' ]

…It keeps the AND.

I know that all WHERE clauses won't work with safe_upsert but can't we allow the use of AND (and OR?) like so (or in another better way). OR could work if the two columns are different.

@bloatware
Copy link
Copy Markdown
Member

I sometimes do this in plugins, where the queries are under control. But for the core usage the regex pattern looks a bit fragile:

safe_upsert(
    'txp_lang', 
    'data = "My data", event = "public"',
    'data = "TWIST AND SHOUT"'
)

If you find a more robust pattern, I'll be all for it.

@NicolasGraph
Copy link
Copy Markdown
Author

How about that?

@bloatware
Copy link
Copy Markdown
Member

That's better, but still will not work with a=1 AND b=2. And if we add \d (digital) to ('|") collection as before AND delimiter, c="1 AND 1" will break it. Tough case...

@bloatware
Copy link
Copy Markdown
Member

bloatware commented Jul 7, 2016

An easier way would be to pass an array of clauses as $where argument. But I don't know if it helps in your use case.

@NicolasGraph
Copy link
Copy Markdown
Author

Yes, why not; otherwise \d seems to work.

@NicolasGraph
Copy link
Copy Markdown
Author

NicolasGraph commented Jul 7, 2016

Edit: better here.

…but $where as an array would be probably cleaner.

@bloatware
Copy link
Copy Markdown
Member

Still broken for a='1 AND one'. There are also a=NOW() AND b=1 and the likes to treat.

@NicolasGraph
Copy link
Copy Markdown
Author

NicolasGraph commented Jul 7, 2016

This is funny to do but I'm not sure if it makes sense to continue…
Any idea how it could work with an array?
Anyway, I can customize safe_upsert() in my plugin on my side.

@bloatware
Copy link
Copy Markdown
Member

You'd call it like this:

safe_upsert(
    'txp_lang', 
    'data = "My data", event = "public"',
    array('name = "my_data"', 'lang = "en-gb"')
)

If this is ok, I can submit a (backwards compatible) patch.

@vanmelick
Copy link
Copy Markdown
Contributor

Perhaps even this, so it's not even possible to use any operator other than '=' in the where part:

safe_upsert(
    'txp_lang', 
    'data = "My data", event = "public"',
    array('name' => 'my_data', 'lang' => 'en-gb')
)

@bloatware
Copy link
Copy Markdown
Member

Perhaps, but since we need to insure the bwc, it would be inconsistent with former name = "my_data" clauses.

@NicolasGraph
Copy link
Copy Markdown
Author

How about the operator? It would always be AND?

@bloatware
Copy link
Copy Markdown
Member

Only AND, I guess, unless we agree on some natural logic to assign values when a=1 OR b=2 is not found.

@NicolasGraph
Copy link
Copy Markdown
Author

For me, this kind of thing (customized for clarity):

safe_upsert(
    'txp_lang', 
    'data = "My data", event = "public"',
    'name = "my_data" OR lang = "en-gb"'
)

would assign my_data to the column name and en-gb to lang.
However this could be a problem:

safe_upsert(
    'txp_lang', 
    'data = "My data", event = "public"',
    'name = "my_data" OR name = "your_data"'
)

…?

@philwareham
Copy link
Copy Markdown
Member

Bump? Is this targeted for 4.6?

@bloatware
Copy link
Copy Markdown
Member

Is this targeted for 4.6?

Not really, I think. It would make plugins authors life a little more convenient, but we (well, I) don't see a natural way to satisfy all the requirement. The best I can do now is follow Ruud's proposal and treat only AND operator, if nobody finds a better idea.

@NicolasGraph
Copy link
Copy Markdown
Author

I agree, let see if we can find something better for 4.7, pending that plugin authors can build a custom function. I can close this pull request and open an issue…?

@NicolasGraph
Copy link
Copy Markdown
Author

To be continued…

@jools-r
Copy link
Copy Markdown
Member

jools-r commented Mar 2, 2018

I just tripped over this one too (also in combination with setting the language). Has there been a solution to this, or does one have to do this in two stages:

  • check if it exists:
    • if yes, do safe_update with where A AND B,
    • if no, safe_insert with all the columns.

@bloatware
Copy link
Copy Markdown
Member

It should work with AND arrays as suggested by Ruud.

@jools-r
Copy link
Copy Markdown
Member

jools-r commented Mar 3, 2018

Thanks Oleg. That did it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants