A partial archive of https://discourse-mediawiki.wmflabs.org as of Saturday May 21, 2022.

UNION in Database Abstraction Layer [SOLVED]

PukupukuDragon

I want to take rows from the recentchanges table and merge them with certain rows from the logging table. The goal is to get a list of all recent changes including any comments that have been added via the CommentStreams extension.

After experimenting in phpMyAdmin, I found the query that I wanted:

( SELECT rc_timestamp, rc_user_text, rc_namespace, rc_title, rc_comment, rc_this_oldid, rc_last_oldid, rc_log_type, rc_log_action, rc_params
	FROM recentchanges
) UNION ALL (
	SELECT log_timestamp AS rc_timestamp, log_user_text AS rc_user_text, log_namespace AS rc_namespace, log_title AS rc_title, '' AS rc_comment, 0 AS rc_this_oldid, 0 AS rc_last_oldid, log_type AS rc_log_type, log_action AS rc_log_action, '' as rc_params
	FROM logging
	WHERE log_type = 'commentstreams'
)
ORDER BY rc_timestamp
DESC LIMIT 50

This does exactly what I want. The problem is that I do not understand how to communicate this query to the database abstraction layer. I looked at the examples in the MediaWiki manual and read the class reference of Database.php but those only explain how to JOIN two queries, not UNION.

Right now, I’m running a simpler query that only pulls from the recentchanges table. It looks like:

$res = $dbr->select(
	'recentchanges',
	[ 'rc_timestamp', 'rc_user_text', 'rc_namespace', 'rc_title', 'rc_comment', 'rc_this_oldid', 'rc_last_oldid', 'rc_log_type', 'rc_log_action', 'rc_params' ],
	'',
	__METHOD__,
	[ 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => '50' ]
);

If it isn’t possible to add a UNION to this, could someone please explain how to circumvent the Database class and issue MySQL / postgreSQL queries directly to the database via strings?

Ciencia-Al-Poder

There’s a unionQueries method for doing that.

See this example

PukupukuDragon

I’m sorry, I don’t understand from that example or documentation what I’m supposed to do. I don’t see a call to unionQueries anywhere in that code and it looks to me like unionQueries returns a string rather than an array of results like select.

Could you give me a trivial example of constructing a UNION query (and renaming the columns of one SELECT as I’ve done). Alternately, can you show me how to circumvent the abstraction layer entirely? I don’t mind having to construct two different queries for two different databases to increase compatibility.

Ciencia-Al-Poder

The link should navigate you to the code where unionQueries is used and even highlight that line. In case you missed it, here’s a sketch:

I think the example is pretty self-explanatory

PukupukuDragon

My bad. I was viewing this on a phone and it scrolled to the wrong bit of code. query seems to be what I was looking for. Thank you.