@@ -297,6 +297,7 @@ extension Table {
297297}
298298
299299public struct _SelectClauses : Sendable {
300+ var isEmpty = false
300301 var distinct = false
301302 var columns : [ any QueryExpression ] = [ ]
302303 var joins : [ _JoinClause ] = [ ]
@@ -320,6 +321,11 @@ public struct Select<Columns, From: Table, Joins> {
320321 // NB: A parameter pack compiler crash forces us to heap-allocate this storage.
321322 @CopyOnWrite var clauses = _SelectClauses ( )
322323
324+ fileprivate var isEmpty : Bool {
325+ get { clauses. isEmpty }
326+ set { clauses. isEmpty = newValue }
327+ _modify { yield & clauses. isEmpty }
328+ }
323329 fileprivate var distinct : Bool {
324330 get { clauses. distinct }
325331 set { clauses. distinct = newValue }
@@ -362,6 +368,7 @@ public struct Select<Columns, From: Table, Joins> {
362368 }
363369
364370 fileprivate init (
371+ isEmpty: Bool ,
365372 distinct: Bool ,
366373 columns: [ any QueryExpression ] ,
367374 joins: [ _JoinClause ] ,
@@ -371,6 +378,7 @@ public struct Select<Columns, From: Table, Joins> {
371378 order: [ QueryFragment ] ,
372379 limit: _LimitClause ?
373380 ) {
381+ self . isEmpty = isEmpty
374382 self . columns = columns
375383 self . distinct = distinct
376384 self . joins = joins
@@ -387,7 +395,8 @@ public struct Select<Columns, From: Table, Joins> {
387395}
388396
389397extension Select {
390- init ( where: [ QueryFragment ] = [ ] ) {
398+ init ( isEmpty: Bool = false , where: [ QueryFragment ] = [ ] ) {
399+ self . isEmpty = isEmpty
391400 self . where = `where`
392401 }
393402
@@ -558,6 +567,7 @@ extension Select {
558567 Joins == ( repeat each J )
559568 {
560569 Select< ( repeat each C1, repeat ( each C2) . QueryValue) , From, ( repeat each J) > (
570+ isEmpty: isEmpty,
561571 distinct: distinct,
562572 columns: columns + Array( repeat each selection( ( From . columns, repeat ( each J) . columns) ) ) ,
563573 joins: joins,
@@ -612,6 +622,7 @@ extension Select {
612622 )
613623 )
614624 return Select < ( repeat each C1 , repeat each C2 ) , From , ( repeat each J1 , F , repeat each J2 ) > (
625+ isEmpty: isEmpty || other. isEmpty,
615626 distinct: distinct || other. distinct,
616627 columns: columns + other. columns,
617628 joins: joins + [ join] + other. joins,
@@ -651,6 +662,7 @@ extension Select {
651662 )
652663 )
653664 return Select < ( repeat each C1 , repeat each C2 ) , From , ( repeat each J , F ) > (
665+ isEmpty: isEmpty || other. isEmpty,
654666 distinct: distinct || other. distinct,
655667 columns: columns + other. columns,
656668 joins: joins + [ join] + other. joins,
@@ -686,6 +698,7 @@ extension Select {
686698 )
687699 )
688700 return Select < QueryValue , From , ( F , repeat each J ) > (
701+ isEmpty: isEmpty || other. isEmpty,
689702 distinct: distinct || other. distinct,
690703 columns: columns + other. columns,
691704 joins: joins + [ join] + other. joins,
@@ -738,6 +751,7 @@ extension Select {
738751 From,
739752 ( repeat each J1, F . _Optionalized, repeat ( each J2) . _Optionalized)
740753 > (
754+ isEmpty: isEmpty || other. isEmpty,
741755 distinct: distinct || other. distinct,
742756 columns: columns + other. columns,
743757 joins: joins + [ join] + other. joins,
@@ -785,6 +799,7 @@ extension Select {
785799 From,
786800 ( repeat each J, F . _Optionalized)
787801 > (
802+ isEmpty: isEmpty || other. isEmpty,
788803 distinct: distinct || other. distinct,
789804 columns: columns + other. columns,
790805 joins: joins + [ join] + other. joins,
@@ -822,6 +837,7 @@ extension Select {
822837 )
823838 )
824839 return Select < QueryValue , From , ( F . _Optionalized , repeat ( each J ) . _Optionalized ) > (
840+ isEmpty: isEmpty || other. isEmpty,
825841 distinct: distinct || other. distinct,
826842 columns: columns + other. columns,
827843 joins: joins + [ join] + other. joins,
@@ -874,6 +890,7 @@ extension Select {
874890 From . _Optionalized,
875891 ( repeat ( each J1) . _Optionalized, F, repeat each J2)
876892 > (
893+ isEmpty: isEmpty || other. isEmpty,
877894 distinct: distinct || other. distinct,
878895 columns: columns + other. columns,
879896 joins: joins + [ join] + other. joins,
@@ -921,6 +938,7 @@ extension Select {
921938 From . _Optionalized,
922939 ( repeat ( each J) . _Optionalized, F)
923940 > (
941+ isEmpty: isEmpty || other. isEmpty,
924942 distinct: distinct || other. distinct,
925943 columns: columns + other. columns,
926944 joins: joins + [ join] + other. joins,
@@ -958,6 +976,7 @@ extension Select {
958976 )
959977 )
960978 return Select < QueryValue , From . _Optionalized , ( F , repeat each J ) > (
979+ isEmpty: isEmpty || other. isEmpty,
961980 distinct: distinct || other. distinct,
962981 columns: columns + other. columns,
963982 joins: joins + [ join] + other. joins,
@@ -1010,6 +1029,7 @@ extension Select {
10101029 From . _Optionalized,
10111030 ( repeat ( each J1) . _Optionalized, F . _Optionalized, repeat ( each J2) . _Optionalized)
10121031 > (
1032+ isEmpty: isEmpty || other. isEmpty,
10131033 distinct: distinct || other. distinct,
10141034 columns: columns + other. columns,
10151035 joins: joins + [ join] + other. joins,
@@ -1057,6 +1077,7 @@ extension Select {
10571077 From . _Optionalized,
10581078 ( repeat ( each J) . _Optionalized, F . _Optionalized)
10591079 > (
1080+ isEmpty: isEmpty || other. isEmpty,
10601081 distinct: distinct || other. distinct,
10611082 columns: columns + other. columns,
10621083 joins: joins + [ join] + other. joins,
@@ -1094,6 +1115,7 @@ extension Select {
10941115 )
10951116 )
10961117 return Select < QueryValue , From . _Optionalized , ( F . _Optionalized , repeat ( each J ) . _Optionalized ) > (
1118+ isEmpty: isEmpty || other. isEmpty,
10971119 distinct: distinct || other. distinct,
10981120 columns: columns + other. columns,
10991121 joins: joins + [ join] + other. joins,
@@ -1348,6 +1370,7 @@ extension Select {
13481370 SQLQueryExpression ( iterator. next ( ) !. queryFragment)
13491371 }
13501372 return Select< ( repeat ( each C2) . QueryValue) , From, Joins> (
1373+ isEmpty: isEmpty,
13511374 distinct: distinct,
13521375 columns: Array ( repeat each transform( repeat { _ in next ( ) } ( ( each C1) . self) ) ) ,
13531376 joins: joins,
@@ -1358,6 +1381,23 @@ extension Select {
13581381 limit: limit
13591382 )
13601383 }
1384+
1385+ /// Returns a fully unscoped version of this select statement.
1386+ public var unscoped : Where < From > {
1387+ From . unscoped
1388+ }
1389+
1390+ /// Returns this select statement unchanged.
1391+ public var all : Self {
1392+ self
1393+ }
1394+
1395+ /// Returns an empty select statement.
1396+ public var none : Self {
1397+ var select = self
1398+ select. isEmpty = true
1399+ return select
1400+ }
13611401}
13621402
13631403/// Combines two select statements of the same table type together.
@@ -1387,6 +1427,7 @@ public func + <
13871427 return Select <
13881428 ( repeat each C1 , repeat each C2 ) , From , ( repeat each J1 , repeat each J2 )
13891429 > (
1430+ isEmpty: lhs. isEmpty || rhs. isEmpty,
13901431 distinct: lhs. distinct || rhs. distinct,
13911432 columns: lhs. columns + rhs. columns,
13921433 joins: lhs. joins + rhs. joins,
@@ -1406,6 +1447,7 @@ extension Select: SelectStatement {
14061447 }
14071448
14081449 public var query : QueryFragment {
1450+ guard !isEmpty else { return " " }
14091451 var query : QueryFragment = " SELECT "
14101452 let columns =
14111453 columns. isEmpty
0 commit comments