diff --git a/uppsrc/Sql/SqlSet.cpp b/uppsrc/Sql/SqlSet.cpp index 01ded37cf..cf021f4f9 100644 --- a/uppsrc/Sql/SqlSet.cpp +++ b/uppsrc/Sql/SqlSet.cpp @@ -8,6 +8,13 @@ SqlSet operator|(const SqlSet& s1, const SqlSet& s2) { return SqlSet(s1(SqlSet::SET, ~SQLITE3) + " union " + s2(SqlSet::SET, ~SQLITE3), SqlSet::SETOP); } +SqlSet operator+(const SqlSet& s1, const SqlSet& s2) +{ + if(s1.IsEmpty()) return s2; + if(s2.IsEmpty()) return s1; + return SqlSet(s1(SqlSet::SET, ~SQLITE3) + " union all " + s2(SqlSet::SET, ~SQLITE3), SqlSet::SETOP); +} + SqlSet operator&(const SqlSet& s1, const SqlSet& s2) { if(s1.IsEmpty()) return s2; if(s2.IsEmpty()) return s1; diff --git a/uppsrc/Sql/SqlStatement.cpp b/uppsrc/Sql/SqlStatement.cpp index 3ff1c91af..5fa00320a 100644 --- a/uppsrc/Sql/SqlStatement.cpp +++ b/uppsrc/Sql/SqlStatement.cpp @@ -34,6 +34,11 @@ SqlSelect& SqlSelect::operator|=(const SqlSelect& s2) { return SetOp(s2, " union "); } +SqlSelect& SqlSelect::operator+=(const SqlSelect& s2) +{ + return SetOp(s2, " union all "); +} + SqlSelect& SqlSelect::operator&=(const SqlSelect& s2) { return SetOp(s2, " intersect "); } @@ -60,6 +65,13 @@ SqlSelect operator-(const SqlSelect& s1, const SqlSelect& s2) { return s; } +SqlSelect operator+(const SqlSelect& s1, const SqlSelect& s2) +{ + SqlSelect s = s1; + s += s2; + return s; +} + SqlSelect& SqlSelect::Where(const SqlBool& exp) { if(!exp.IsTrue() && !exp.IsEmpty()) text << " where " << ~exp; diff --git a/uppsrc/Sql/Sqlexp.h b/uppsrc/Sql/Sqlexp.h index e9d788289..2a4314aec 100644 --- a/uppsrc/Sql/Sqlexp.h +++ b/uppsrc/Sql/Sqlexp.h @@ -433,6 +433,7 @@ class Sql; #define E__SqlVal(I) const SqlVal& p##I SqlSet operator|(const SqlSet& s1, const SqlSet& s2); // union +SqlSet operator+(const SqlSet& s1, const SqlSet& s2); // union all SqlSet operator&(const SqlSet& s1, const SqlSet& s2); // intersection SqlSet operator-(const SqlSet& s1, const SqlSet& s2); // difference @@ -462,6 +463,7 @@ public: SqlSet& operator<<(const SqlVal& val) { return Cat(val); } SqlSet& operator|=(const SqlSet& set) { return *this = *this | set; } + SqlSet& operator+=(const SqlSet& set) { return *this = *this + set; } SqlSet& operator&=(const SqlSet& set) { return *this = *this & set; } SqlSet& operator-=(const SqlSet& set) { return *this = *this - set; } @@ -604,9 +606,10 @@ __Expand(E__QSelect); bool IsEmpty() { return text.IsEmpty(); } - SqlSelect& operator|=(const SqlSelect& s2); - SqlSelect& operator&=(const SqlSelect& s2); - SqlSelect& operator-=(const SqlSelect& s2); + SqlSelect& operator|=(const SqlSelect& s2); // union + SqlSelect& operator&=(const SqlSelect& s2); // intersect + SqlSelect& operator-=(const SqlSelect& s2); // except + SqlSelect& operator+=(const SqlSelect& s2); // union all //Deprecated!!! bool Execute(Sql& sql) const { return SqlStatement(*this).Execute(sql); } @@ -617,9 +620,10 @@ __Expand(E__QSelect); Value Fetch() const { return SqlStatement(*this).Fetch(); } }; -SqlSelect operator|(const SqlSelect& s1, const SqlSelect& s2); -SqlSelect operator&(const SqlSelect& s1, const SqlSelect& s2); -SqlSelect operator-(const SqlSelect& s1, const SqlSelect& s2); +SqlSelect operator|(const SqlSelect& s1, const SqlSelect& s2); // union +SqlSelect operator&(const SqlSelect& s1, const SqlSelect& s2); // intersect +SqlSelect operator-(const SqlSelect& s1, const SqlSelect& s2); // except +SqlSelect operator+(const SqlSelect& s1, const SqlSelect& s2); // union all inline SqlSelect SelectAll() { return SqlSelect(SqlAll()); } inline SqlSelect Select(const SqlSet& set) { return SqlSelect(set); } diff --git a/uppsrc/Sql/src.tpp/SqlExp$en-us.tpp b/uppsrc/Sql/src.tpp/SqlExp$en-us.tpp index c5f839cdf..2c540cae6 100644 --- a/uppsrc/Sql/src.tpp/SqlExp$en-us.tpp +++ b/uppsrc/Sql/src.tpp/SqlExp$en-us.tpp @@ -264,30 +264,26 @@ topic "SqlExp in examples"; :: [s0;%- [C1 select COLUMN]&] [s0;%- [C1 from TABLE]&] [s0;%- [C1 where ][*C1 not exists (select COLUMN from TABLE1)]] -:: [s0;%- [C1 Select(COLUMN)]&] -[s0;%- [C1 .From(TABLE)]&] -[s0;%- [C1 .Where(COLUMN `=`= (][*C1 Select(COLUMN1).From(TABLE1) `|]&] -[s0;%- [*C1 Select(COLUMN2).From(TABLE2)][C1 ))]] -:: [s0;%- [C1 select COLUMN]&] -[s0;%- [C1 from TABLE]&] -[s0;%- [C1 where COLUMN in (][*C1 select COLUMN1 from TABLE1]&] -[s0;%- [*C1 union (select COLUMN2 from TABLE2)][C1 )]] -:: [s0;%- [C1 Select(COLUMN)]&] -[s0;%- [C1 .From(TABLE)]&] -[s0;%- [C1 .Where(COLUMN `=`= (][*C1 Select(COLUMN1).From(TABLE1) `&]&] -[s0;%- [*C1 Select(COLUMN2).From(TABLE2)][C1 ))]] -:: [s0;%- [C1 select COLUMN]&] -[s0;%- [C1 from TABLE]&] -[s0;%- [C1 where COLUMN in (][*C1 select COLUMN1 from TABLE1]&] -[s0;%- [*C1 intersect (select COLUMN2 from TABLE2)][C1 )]] -:: [s0;%- [C1 Select(COLUMN)]&] -[s0;%- [C1 .From(TABLE)]&] -[s0;%- [C1 .Where(COLUMN `=`= (][*C1 Select(COLUMN1).From(TABLE1) `-]&] -[s0;%- [*C1 Select(COLUMN2).From(TABLE2)))]] -:: [s0;%- [C1 select COLUMN]&] -[s0;%- [C1 from TABLE]&] -[s0;%- [C1 where COLUMN in (][*C1 select COLUMN1 from TABLE1]&] -[s0;%- [*C1 minus (select COLUMN2 from TABLE2)][C1 )]] +:: [s0;%- [C1 Select(COLUMN1)]&] +[s0;%- [C1 .From(TABLE1)]&] +[s0;%- [*C1 `|][C1 Select(COLUMN2).From(TABLE2)]] +:: [s0;%- [C1 ((select COLUMN1 from TABLE1)]&] +[s0;%- [*C1 union ][C1 (select COLUMN2 from TABLE2))]] +:: [s0;%- [C1 Select(COLUMN1)]&] +[s0;%- [C1 .From(TABLE1)]&] +[s0;%- [*C1 `+][C1 Select(COLUMN2).From(TABLE2)]] +:: [s0;%- [C1 ((select COLUMN1 from TABLE1)]&] +[s0;%- [*C1 union all][C1 (select COLUMN2 from TABLE2))]] +:: [s0;%- [C1 Select(COLUMN1)]&] +[s0;%- [C1 .From(TABLE1)]&] +[s0;%- [*C1 `&][C1 Select(COLUMN2).From(TABLE2)]] +:: [s0;%- [C1 ((select COLUMN1 from TABLE1)]&] +[s0;%- [*C1 intersect ][C1 (select COLUMN2 from TABLE2))]] +:: [s0;%- [C1 Select(COLUMN1)]&] +[s0;%- [C1 .From(TABLE1)]&] +[s0;%- [*C1 `-][C1 Select(COLUMN2).From(TABLE2)]] +:: [s0;%- [C1 ((select COLUMN1 from TABLE1)]&] +[s0;%- [*C1 except ][C1 (select COLUMN2 from TABLE2))]] :: [s0;%- [C1 Select(COLUMN)]&] [s0;%- [C1 .From(TABLE)]&] [s0;%- [C1 .Where(COLUMN `=`= 0)]&]