From f776438ffc97bb813dcfd37fb7ccd1c464e7ce80 Mon Sep 17 00:00:00 2001 From: Tim MacDonald Date: Tue, 22 Oct 2024 00:53:19 +1100 Subject: [PATCH] Improve query builder tests (#53251) * Improve query builder tests * Lint --- tests/Database/DatabaseQueryBuilderTest.php | 313 ++++++++++++++++++++ 1 file changed, 313 insertions(+) diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index d635a7e2efc..4e053c34cdf 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -2316,8 +2316,43 @@ public function testWhereShortcut() $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings()); } + public function testOrWheresHaveConsistentResults() + { + $queries = []; + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere(['foo' => 1, 'bar' => 2]); + $queries[] = $builder->toSql(); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere([['foo', 1], ['bar', 2]]); + $queries[] = $builder->toSql(); + + $this->assertSame([ + 'select * from "users" where "xxxx" = ? or ("foo" = ? or "bar" = ?)', + 'select * from "users" where "xxxx" = ? or ("foo" = ? or "bar" = ?)', + ], $queries); + + $queries = []; + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereColumn(['foo' => '_foo', 'bar' => '_bar']); + $queries[] = $builder->toSql(); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereColumn([['foo', '_foo'], ['bar', '_bar']]); + $queries[] = $builder->toSql(); + + $this->assertSame([ + 'select * from "users" where "xxxx" = ? or ("foo" = "_foo" or "bar" = "_bar")', + 'select * from "users" where "xxxx" = ? or ("foo" = "_foo" or "bar" = "_bar")', + ], $queries); + } + public function testWhereWithArrayConditions() { + /* + * where(key, value) + */ + $builder = $this->getBuilder(); $builder->select('*')->from('users')->where([['foo', 1], ['bar', 2]]); $this->assertSame('select * from "users" where ("foo" = ? and "bar" = ?)', $builder->toSql()); @@ -2328,6 +2363,11 @@ public function testWhereWithArrayConditions() $this->assertSame('select * from "users" where ("foo" = ? or "bar" = ?)', $builder->toSql()); $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where([['foo', 1], ['bar', 2]], boolean: 'and'); + $this->assertSame('select * from "users" where ("foo" = ? and "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + $builder = $this->getBuilder(); $builder->select('*')->from('users')->where(['foo' => 1, 'bar' => 2]); $this->assertSame('select * from "users" where ("foo" = ? and "bar" = ?)', $builder->toSql()); @@ -2338,6 +2378,15 @@ public function testWhereWithArrayConditions() $this->assertSame('select * from "users" where ("foo" = ? or "bar" = ?)', $builder->toSql()); $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where(['foo' => 1, 'bar' => 2], boolean: 'and'); + $this->assertSame('select * from "users" where ("foo" = ? and "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + /* + * where(key, <, value) + */ + $builder = $this->getBuilder(); $builder->select('*')->from('users')->where([['foo', 1], ['bar', '<', 2]]); $this->assertSame('select * from "users" where ("foo" = ? and "bar" < ?)', $builder->toSql()); @@ -2347,6 +2396,270 @@ public function testWhereWithArrayConditions() $builder->select('*')->from('users')->where([['foo', 1], ['bar', '<', 2]], boolean: 'or'); $this->assertSame('select * from "users" where ("foo" = ? or "bar" < ?)', $builder->toSql()); $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where([['foo', 1], ['bar', '<', 2]], boolean: 'and'); + $this->assertSame('select * from "users" where ("foo" = ? and "bar" < ?)', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + /* + * whereNot(key, value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', 2]]); + $this->assertSame('select * from "users" where not (("foo" = ? and "bar" = ?))', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', 2]], boolean: 'or'); + $this->assertSame('select * from "users" where not (("foo" = ? or "bar" = ?))', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', 2]], boolean: 'and'); + $this->assertSame('select * from "users" where not (("foo" = ? and "bar" = ?))', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNot(['foo' => 1, 'bar' => 2]); + $this->assertSame('select * from "users" where not (("foo" = ? and "bar" = ?))', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNot(['foo' => 1, 'bar' => 2], boolean: 'or'); + $this->assertSame('select * from "users" where not (("foo" = ? or "bar" = ?))', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNot(['foo' => 1, 'bar' => 2], boolean: 'and'); + $this->assertSame('select * from "users" where not (("foo" = ? and "bar" = ?))', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + /* + * whereNot(key, <, value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', '<', 2]]); + $this->assertSame('select * from "users" where not (("foo" = ? and "bar" < ?))', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', '<', 2]], boolean: 'or'); + $this->assertSame('select * from "users" where not (("foo" = ? or "bar" < ?))', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', '<', 2]], boolean: 'and'); + $this->assertSame('select * from "users" where not (("foo" = ? and "bar" < ?))', $builder->toSql()); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + + /* + * whereColumn(col1, col2) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '_bar']]); + $this->assertSame('select * from "users" where ("foo" = "_foo" and "bar" = "_bar")', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '_bar']], boolean: 'or'); + $this->assertSame('select * from "users" where ("foo" = "_foo" or "bar" = "_bar")', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '_bar']], boolean: 'and'); + $this->assertSame('select * from "users" where ("foo" = "_foo" and "bar" = "_bar")', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereColumn(['foo' => '_foo', 'bar' => '_bar']); + $this->assertSame('select * from "users" where ("foo" = "_foo" and "bar" = "_bar")', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereColumn(['foo' => '_foo', 'bar' => '_bar'], boolean: 'or'); + $this->assertSame('select * from "users" where ("foo" = "_foo" or "bar" = "_bar")', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereColumn(['foo' => '_foo', 'bar' => '_bar'], boolean: 'and'); + $this->assertSame('select * from "users" where ("foo" = "_foo" and "bar" = "_bar")', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + + /* + * whereColumn(col1, <, col2) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '<', '_bar']]); + $this->assertSame('select * from "users" where ("foo" = "_foo" and "bar" < "_bar")', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '<', '_bar']], boolean: 'or'); + $this->assertSame('select * from "users" where ("foo" = "_foo" or "bar" < "_bar")', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '<', '_bar']], boolean: 'and'); + $this->assertSame('select * from "users" where ("foo" = "_foo" and "bar" < "_bar")', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + + /* + * whereAll([...keys], value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereAll(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where ("foo" = ? and "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereAll(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where ("foo" = ? and "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings()); + + /* + * whereAny([...keys], value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereAny(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where ("foo" = ? or "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereAny(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where ("foo" = ? or "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings()); + + /* + * whereNone([...keys], value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNone(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where not ("foo" = ? or "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNone(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where not ("foo" = ? or "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings()); + + /* + * where()->orWhere(key, value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere([['foo', 1], ['bar', 2]]); + $this->assertSame('select * from "users" where "xxxx" = ? or ("foo" = ? or "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere(['foo' => 1, 'bar' => 2]); + $this->assertSame('select * from "users" where "xxxx" = ? or ("foo" = ? or "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings()); + + /* + * where()->orWhere(key, <, value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere([['foo', 1], ['bar', '<', 2]]); + $this->assertSame('select * from "users" where "xxxx" = ? or ("foo" = ? or "bar" < ?)', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings()); + + /* + * where()->orWhereColumn(col1, col2) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereColumn([['foo', '_foo'], ['bar', '_bar']]); + $this->assertSame('select * from "users" where "xxxx" = ? or ("foo" = "_foo" or "bar" = "_bar")', $builder->toSql()); + $this->assertEquals([0 => 'xxxx'], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereColumn(['foo' => '_foo', 'bar' => '_bar']); + $this->assertSame('select * from "users" where "xxxx" = ? or ("foo" = "_foo" or "bar" = "_bar")', $builder->toSql()); + $this->assertEquals([0 => 'xxxx'], $builder->getBindings()); + + /* + * where()->orWhere(key, <, value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere([['foo', 1], ['bar', '<', 2]]); + $this->assertSame('select * from "users" where "xxxx" = ? or ("foo" = ? or "bar" < ?)', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings()); + + /* + * where()->orWhereNot(key, value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereNot([['foo', 1], ['bar', 2]]); + $this->assertSame('select * from "users" where "xxxx" = ? or not (("foo" = ? or "bar" = ?))', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereNot(['foo' => 1, 'bar' => 2]); + $this->assertSame('select * from "users" where "xxxx" = ? or not (("foo" = ? or "bar" = ?))', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings()); + + /* + * where()->orWhereNot(key, <, value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereNot([['foo', 1], ['bar', '<', 2]]); + $this->assertSame('select * from "users" where "xxxx" = ? or not (("foo" = ? or "bar" < ?))', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings()); + + /* + * where()->orWhereAll([...keys], value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereAll(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where "xxxx" = ? or ("foo" = ? and "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereAll(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where "xxxx" = ? or ("foo" = ? and "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings()); + + /* + * where()->orWhereAny([...keys], value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereAny(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where "xxxx" = ? or ("foo" = ? or "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereAny(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where "xxxx" = ? or ("foo" = ? or "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings()); + + /* + * where()->orWhereNone([...keys], value) + */ + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereNone(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where "xxxx" = ? or not ("foo" = ? or "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereNone(['foo', 'bar'], 2); + $this->assertSame('select * from "users" where "xxxx" = ? or not ("foo" = ? or "bar" = ?)', $builder->toSql()); + $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings()); } public function testNestedWheres()