You can try for example:
add_action( 'pre_get_posts', function( $q ) {
if( $q->is_main_query() && $q->is_search() )
{
$q->set( 'nopaging', true );
add_filter( 'posts_request', function( $request ) {
$sql = 'YOUR EXTRA SQL QUERY';
return "(" . $request . ") UNION ({$sql}) ORDER BY post_status DESC";
});
}
});
where we use the no paging version to match your SQL query.
Update:
Well, if I understand your comment correctly you want to reuse the main search query in your extra SQL query. Here's one hacky version:
add_action( 'pre_get_posts', function( $q ) {
if( $q->is_main_query() && $q->is_search() )
{
$q->set( 'nopaging', true );
add_filter( 'posts_orderby', '__return_null' );
add_filter( 'posts_request', function( $request ) {
global $wpdb;
$sql = strstr( $request, "AND {$wpdb->posts}.post_type IN", true );
$sql = str_ireplace( "FROM {$wpdb->posts}", "FROM {$wpdb->prefix}software_and_hardware_post", $sql );
$sql = str_ireplace( $wpdb->posts . '.*', 'ID, title as post_title, content as post_content ', $sql );
$sql = str_ireplace( $wpdb->posts . '.post_title', 'title', $sql );
$sql = str_ireplace( $wpdb->posts . '.post_content', 'content', $sql );
$sql .= ' AND status = 1';
$request = str_ireplace( $wpdb->posts . '.*', 'ID, post_title, post_content ', $request );
return "(" . $request . " ) UNION ({$sql}) ORDER BY post_status DESC";
});
}
});