Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ export class Converter
// left_sql currently may start with "DB::table('...')" or "->from('...')" when nested; ensure proper prefix
let base = (new Converter(left.Query || left, this).run(false));

// Build union call: pass the right query builder expression as a DB::raw of the SQL from right_converter without trailing get();
// Prefer passing DB::table(...) closure to preserve query builder: use function($query) { $query->from(...)->... }
let right_closure = 'function ($query) {\n\t' + right_sql.replace('DB::table', '$query->from').split('\n').join('\n\t') + ';\n}';
// Build union call: pass the right query builder expression directly (as DB::table(...)->...)
let right_block = right_sql;

let union_section = base + '\n->' + union_method + '(' + right_closure + ')';
// Indent right block and wrap in parentheses as argument to union/unionAll
let union_section = base + '\n->' + union_method + '(\n' + addTabToEveryLine(right_block, 1) + '\n)';

// If top-level has order_by / limit / offset, append them
if (propertyExistsInObjectAndNotNull(this.ast, 'order_by') && this.ast.order_by.length > 0) {
union_section = union_section + '\n->' + (new Converter(this.ast, this).resolveOrderBySection());
} else if (propertyExistsInObjectAndNotNull(this.ast, 'order_by') && this.ast.order_by.length === 0 && propertyExistsInObjectAndNotNull(this.ast.body, 'order_by') && this.ast.body.order_by.length > 0) {
} else if (propertyExistsInObjectAndNotNull(this.ast.body, 'order_by') && this.ast.body.order_by.length > 0) {
union_section = union_section + '\n->' + (new Converter(this.ast.body, this).resolveOrderBySection());
}

Expand Down
23 changes: 11 additions & 12 deletions tests/converter.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import {Converter} from "../src/converter";
import {test, expect} from "@jest/globals";
import {complex_ast} from './ast';
import {cross_join_ast} from './crossjoin';

const {Converter} = require('../src/converter');
const {test, expect} = require('@jest/globals');
const {complex_ast} = require('./ast');
const {cross_join_ast} = require('./crossjoin');

function getQueryBuilder(ast) {
return (new Converter(ast[0].Query).run());
Expand All @@ -14,12 +13,12 @@ test('complex sql', () => {
->leftJoin('comments','comments.post_id','=','posts.id')
->rightJoin('users','user.id','=','posts.user_id')
->leftJoin(DB::raw("DB::table('address')
\t->select('*')") as a), function($join) {
\t$join->on('user.aid','=','a.id');
->select('*')") as a), function($join) {
$join->on('user.aid','=','a.id');
}
->where(function ($query) {
\t$query->where('a.name','=','bejing')
\t\t->where('a.id','<',10);
$query->where('a.name','=','bejing')
->where('a.id','<',10);
})
->where('comments.conent','=','abc')
->orderBy('comments.created_at','asc')
Expand All @@ -30,9 +29,9 @@ test('complex sql', () => {
test('cross join', () => {
expect(getQueryBuilder(cross_join_ast)).toBe(`DB::table('posts')
->crossJoinSub(function ($query) {
\t$query->from('posts')
\t\t->select('count', DB::raw("'max'(created_date) as created_date"))
\t\t->groupBy('count');
$query->from('posts')
->select('count', DB::raw("'max'(created_date) as created_date"))
->groupBy('count');
},'max_counts')
->select('posts.*')
->where('posts.count','=',DB::raw('max_counts.count'))
Expand Down
13 changes: 13 additions & 0 deletions tests/union.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const wasm = require('sqlparser-rs-wasm');
const Converter = require('../src/converter');

test('union all for users where null', () => {
const sql = "(select * from `users` where `last_name` is null) union all (select * from `users` where `first_name` is null) order by id";
const ast = wasm.parse_sql('--mysql', sql);
const conv = new Converter(ast, null);
const out = conv.run(true);

const expected = `DB::table('users')\n->whereNull('last_name')\n->unionAll(\n DB::table('users')\n ->whereNull('first_name')\n)\n->orderBy('id')\n->get();`;

expect(out.replace(/\s+$/g, '')).toBe(expected);
});