You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2022/08/19 15:14:34 UTC

[empire-db] branch master updated: EMPIREDB-394 Replaced StringBuilder with DBSQLBuilder for SQL statement generation

This is an automated email from the ASF dual-hosted git repository.

doebele pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/empire-db.git


The following commit(s) were added to refs/heads/master by this push:
     new 8c556ee5 EMPIREDB-394 Replaced StringBuilder with DBSQLBuilder for SQL statement generation
8c556ee5 is described below

commit 8c556ee5e525eca653838be4ecba906a7fd3f423
Author: Rainer Döbele <do...@apache.org>
AuthorDate: Fri Aug 19 17:14:30 2022 +0200

    EMPIREDB-394
    Replaced StringBuilder with DBSQLBuilder for SQL statement generation
---
 .../main/java/org/apache/empire/db/DBCmdParam.java |   4 +-
 .../main/java/org/apache/empire/db/DBColumn.java   |  10 +-
 .../java/org/apache/empire/db/DBCombinedCmd.java   |  30 ++--
 .../main/java/org/apache/empire/db/DBCommand.java  | 154 +++++++++----------
 .../java/org/apache/empire/db/DBCommandExpr.java   |  83 +++++++----
 .../java/org/apache/empire/db/DBDDLGenerator.java  |  29 ++--
 .../main/java/org/apache/empire/db/DBDatabase.java |  16 +-
 .../src/main/java/org/apache/empire/db/DBExpr.java | 118 +--------------
 .../main/java/org/apache/empire/db/DBQuery.java    |  14 +-
 .../empire/db/{DBExpr.java => DBSQLBuilder.java}   | 163 +++++++++++++++------
 .../java/org/apache/empire/db/DBSQLScript.java     |   4 +-
 .../main/java/org/apache/empire/db/DBTable.java    |  10 +-
 .../src/main/java/org/apache/empire/db/DBView.java |  10 +-
 .../empire/db/expr/column/DBAbstractFuncExpr.java  |   5 +-
 .../apache/empire/db/expr/column/DBAliasExpr.java  |  13 +-
 .../apache/empire/db/expr/column/DBCalcExpr.java   |  11 +-
 .../apache/empire/db/expr/column/DBCaseExpr.java   |   3 +-
 .../empire/db/expr/column/DBCaseWhenExpr.java      |  10 +-
 .../empire/db/expr/column/DBCmdResultExpr.java     |   5 +-
 .../empire/db/expr/column/DBCoalesceExpr.java      |   3 +-
 .../apache/empire/db/expr/column/DBConcatExpr.java |  23 +--
 .../empire/db/expr/column/DBConcatFuncExpr.java    |  21 +--
 .../empire/db/expr/column/DBConvertExpr.java       |   3 +-
 .../apache/empire/db/expr/column/DBCountExpr.java  |   3 +-
 .../apache/empire/db/expr/column/DBDecodeExpr.java |  23 ++-
 .../apache/empire/db/expr/column/DBFuncExpr.java   |   3 +-
 .../empire/db/expr/column/DBParenthesisExpr.java   |  11 +-
 .../apache/empire/db/expr/column/DBScalarExpr.java |   7 +-
 .../apache/empire/db/expr/column/DBValueExpr.java  |   9 +-
 .../empire/db/expr/column/DBVarArgsFuncExpr.java   |  31 ++--
 .../empire/db/expr/compare/DBCompareAndOrExpr.java |  29 ++--
 .../empire/db/expr/compare/DBCompareColExpr.java   |  51 +++----
 .../empire/db/expr/compare/DBCompareNotExpr.java   |  13 +-
 .../db/expr/compare/DBCompareParenthesisExpr.java  |   9 +-
 .../empire/db/expr/compare/DBExistsExpr.java       |  21 +--
 .../empire/db/expr/join/DBColumnJoinExpr.java      |  29 ++--
 .../empire/db/expr/join/DBCompareJoinExpr.java     |  23 +--
 .../empire/db/expr/join/DBCrossJoinExpr.java       |   9 +-
 .../apache/empire/db/expr/order/DBOrderByExpr.java |   9 +-
 .../org/apache/empire/db/expr/set/DBSetExpr.java   |   5 +-
 .../java/org/apache/empire/dbms/DBMSHandler.java   |   3 +-
 .../org/apache/empire/dbms/DBMSHandlerBase.java    |  22 ++-
 .../empire/dbms/derby/DerbyDDLGenerator.java       |   5 +-
 .../org/apache/empire/dbms/h2/DBMSHandlerH2.java   |  21 +--
 .../org/apache/empire/dbms/h2/H2DDLGenerator.java  |   3 +-
 .../org/apache/empire/dbms/hsql/DBCommandHSql.java |  53 +++----
 .../apache/empire/dbms/hsql/DBMSHandlerHSql.java   |   3 +-
 .../apache/empire/dbms/hsql/HSqlDDLGenerator.java  |   3 +-
 .../apache/empire/dbms/mysql/DBMSHandlerMySQL.java |  35 ++---
 .../empire/dbms/mysql/MySQLDDLGenerator.java       |   7 +-
 .../apache/empire/dbms/oracle/DBCommandOracle.java | 109 +++++++-------
 .../empire/dbms/oracle/DBMSHandlerOracle.java      |  21 +--
 .../empire/dbms/oracle/OracleDDLGenerator.java     |   7 +-
 .../empire/dbms/oracle/OracleRowNumExpr.java       |   7 +-
 .../empire/dbms/postgresql/DBCommandPostgres.java  |  43 +++---
 .../dbms/postgresql/DBMSHandlerPostgreSQL.java     |   3 +-
 .../empire/dbms/postgresql/PostgresAtAt.java       |   9 +-
 .../dbms/postgresql/PostgresBoolAndOrExpr.java     |  11 +-
 .../dbms/postgresql/PostgresDDLGenerator.java      |   7 +-
 .../empire/dbms/postgresql/PostgresFuncExpr.java   |   3 +-
 .../empire/dbms/sqlite/SQLiteDDLGenerator.java     |   3 +-
 .../empire/dbms/sqlserver/DBMSHandlerMSSQL.java    |  38 +++--
 .../empire/dbms/sqlserver/MSSqlDDLGenerator.java   |   7 +-
 .../apache/empire/db/expr/set/DBSetExprTest.java   |  13 +-
 64 files changed, 749 insertions(+), 714 deletions(-)

diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java b/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
index 0118385b..e1ffc31e 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
@@ -98,9 +98,9 @@ public class DBCmdParam extends DBExpr
     }
     
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
-        buf.append("?"); //$NON-NLS-1$
+        sql.append("?"); //$NON-NLS-1$
         // Move to current usage position
         cmd.notifyParamUsage(this);
     }
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBColumn.java b/empire-db/src/main/java/org/apache/empire/db/DBColumn.java
index 3063b1f6..a94ab3fe 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBColumn.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBColumn.java
@@ -230,24 +230,24 @@ public abstract class DBColumn extends DBColumnExpr
      * Adds the colunm name to the SQL-Command. <br>
      * This can be either a qualified or unqualified name depending on the context.
      *
-     * @param buf the SQL statment
+     * @param sql the SQL statment
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     { 
         // Append rowset alias
         if ((context & CTX_FULLNAME) != 0)
         {   // Fully Qualified Name
-            buf.append(rowset.getAlias());
-            buf.append(".");
+            sql.append(rowset.getAlias());
+            sql.append(".");
         }
         // Append the name
         DBMSHandler dbms = getDatabase().getDbms();
         if (dbms==null)
         	throw new DatabaseNotOpenException(getDatabase());
         // Append the name
-        dbms.appendObjectName(buf, name, quoteName);
+        dbms.appendObjectName(sql, name, quoteName);
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCombinedCmd.java b/empire-db/src/main/java/org/apache/empire/db/DBCombinedCmd.java
index 3037b462..738e2451 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCombinedCmd.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCombinedCmd.java
@@ -164,41 +164,41 @@ public class DBCombinedCmd extends DBCommandExpr
     /**
      * Creates the SQL-Command.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      */
     @Override
-    public void getSelect(StringBuilder buf)
+    public void getSelect(DBSQLBuilder sql)
     {
         // the left part
         left.clearOrderBy();
         if (!(left instanceof DBCombinedCmd))
         {
-            buf.append("(");
-            left.getSelect(buf);
-            buf.append(")");
+            sql.append("(");
+            left.getSelect(sql);
+            sql.append(")");
         }
         else
-            left.getSelect(buf);
+            left.getSelect(sql);
         // concat keyword
-        buf.append("\r\n");
-        buf.append(keyWord);
-        buf.append("\r\n");
+        sql.append("\r\n");
+        sql.append(keyWord);
+        sql.append("\r\n");
         // the right part
         right.clearOrderBy();
         if (!(right instanceof DBCombinedCmd))
         {
-            buf.append("(");
-            right.getSelect(buf);
-            buf.append(")");
+            sql.append("(");
+            right.getSelect(sql);
+            sql.append(")");
         }
         else
-            right.getSelect(buf);
+            right.getSelect(sql);
         // done
         // Add optional Order by statement
         if (orderBy != null)
         { // Having
-            buf.append("\r\nORDER BY ");
-            addListExpr(buf, orderBy, CTX_DEFAULT, ", ");
+            sql.append("\r\nORDER BY ");
+            addListExpr(sql, orderBy, CTX_DEFAULT, ", ");
         }
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
index 7a9a405a..3b28779c 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
@@ -1595,21 +1595,21 @@ public abstract class DBCommand extends DBCommandExpr
      * @return a select SQL-Statement
      */
     @Override
-    public void getSelect(StringBuilder buf)
+    public void getSelect(DBSQLBuilder sql)
     {
         resetParamUsage();
         if (select == null)
             throw new ObjectNotValidException(this); // invalid!
         // Prepares statement
-        addSelect(buf);
+        addSelect(sql);
         // From clause
-        addFrom(buf);
+        addFrom(sql);
         // Add Where
-        addWhere(buf);
+        addWhere(sql);
         // Add Grouping
-        addGrouping(buf);
+        addGrouping(sql);
         // Add Order
-        addOrder(buf);
+        addOrder(sql);
         // done
         completeParamUsage();
     }
@@ -1625,12 +1625,12 @@ public abstract class DBCommand extends DBCommandExpr
         resetParamUsage();
         if (set==null || set.get(0)==null)
             return null;
-        StringBuilder buf = new StringBuilder("INSERT INTO ");
-        // addTableExpr(buf, CTX_NAME);
+        DBSQLBuilder sql = createSQLBuilder("INSERT INTO ");
+        // addTableExpr(sql, CTX_NAME);
         DBRowSet table =  set.get(0).getTable();
-        table.addSQL(buf, CTX_FULLNAME);
+        table.addSQL(sql, CTX_FULLNAME);
         // Set Expressions
-        buf.append("( ");
+        sql.append("( ");
         // Set Expressions
         ArrayList<DBCompareColExpr> compexpr = null;
         if (where!=null && !where.isEmpty())
@@ -1644,10 +1644,10 @@ public abstract class DBCommand extends DBCommandExpr
             if (compexpr.size()>0)
             {
                 // add List
-                addListExpr(buf, compexpr, CTX_NAME, ", ");
+                addListExpr(sql, compexpr, CTX_NAME, ", ");
                 // add separator
                 if (set != null)
-                    buf.append(", ");
+                    sql.append(", ");
             }
             else
             {   // No columns to set
@@ -1655,20 +1655,20 @@ public abstract class DBCommand extends DBCommandExpr
             }
         }
         if (set != null)
-            addListExpr(buf, set, CTX_NAME, ", ");
+            addListExpr(sql, set, CTX_NAME, ", ");
         // Values
-        buf.append(") VALUES ( ");
+        sql.append(") VALUES ( ");
         if (compexpr != null)
-            addListExpr(buf, compexpr, CTX_VALUE, ", ");
+            addListExpr(sql, compexpr, CTX_VALUE, ", ");
         if (compexpr != null && set != null)
-            buf.append(", ");
+            sql.append(", ");
         if (set != null)
-            addListExpr(buf, set, CTX_VALUE, ", ");
+            addListExpr(sql, set, CTX_VALUE, ", ");
         // End
-        buf.append(")");
+        sql.append(")");
         // done
         completeParamUsage();
-        return buf.toString();
+        return sql.toString();
     }
     
     /**
@@ -1710,43 +1710,43 @@ public abstract class DBCommand extends DBCommandExpr
         resetParamUsage();
         if (set == null)
             return null;
-        StringBuilder buf = new StringBuilder("UPDATE ");
+        DBSQLBuilder sql = createSQLBuilder("UPDATE ");
         DBRowSet table =  set.get(0).getTable();
         if (joins!=null && !joins.isEmpty())
         {   // Join Update
-            addUpdateWithJoins(buf, table);
+            addUpdateWithJoins(sql, table);
         }
         else
         {   // Simple Statement
-            addUpdateForTable(buf, table);
+            addUpdateForTable(sql, table);
         }
         // done
         completeParamUsage();
-        return buf.toString();
+        return sql.toString();
     }
 
-    protected void addUpdateForTable(StringBuilder buf, DBRowSet table)
+    protected void addUpdateForTable(DBSQLBuilder sql, DBRowSet table)
     {   // Simple Statement
-        table.addSQL(buf, CTX_FULLNAME);
+        table.addSQL(sql, CTX_FULLNAME);
         long context = CTX_NAME | CTX_VALUE;
         // Set Expressions
-        buf.append("\r\nSET ");
-        addListExpr(buf, set, context, ", ");
+        sql.append("\r\nSET ");
+        addListExpr(sql, set, context, ", ");
         // Add Where
-        addWhere(buf, context);
+        addWhere(sql, context);
     }
     
-    protected void addUpdateWithJoins(StringBuilder buf, DBRowSet table)
+    protected void addUpdateWithJoins(DBSQLBuilder sql, DBRowSet table)
     {   // Join Update
-        buf.append( table.getAlias() );
+        sql.append( table.getAlias() );
         long context = CTX_DEFAULT;
         // Set Expressions
-        buf.append("\r\nSET ");
-        addListExpr(buf, set, context, ", ");
+        sql.append("\r\nSET ");
+        addListExpr(sql, set, context, ", ");
         // From clause
-        addFrom(buf);
+        addFrom(sql);
         // Add Where
-        addWhere(buf, context);
+        addWhere(sql, context);
     }
     
     /**
@@ -1759,54 +1759,54 @@ public abstract class DBCommand extends DBCommandExpr
     public final String getDelete(DBTable table)
     {
         resetParamUsage();
-        StringBuilder buf = new StringBuilder("DELETE ");
+        DBSQLBuilder sql = createSQLBuilder("DELETE ");
         // joins or simple
          if (joins!=null && !joins.isEmpty())
         {   // delete with joins
-            addDeleteWithJoins(buf, table);
+            addDeleteWithJoins(sql, table);
         }
         else
         {   // Simple Statement
-            addDeleteForTable(buf, table);
+            addDeleteForTable(sql, table);
         }
         // done
         completeParamUsage();
-        return buf.toString();
+        return sql.toString();
     }
 
-    protected void addDeleteForTable(StringBuilder buf, DBRowSet table)
+    protected void addDeleteForTable(DBSQLBuilder sql, DBRowSet table)
     {   // Simple Statement
-        buf.append("FROM ");
-        table.addSQL(buf, CTX_FULLNAME);
+        sql.append("FROM ");
+        table.addSQL(sql, CTX_FULLNAME);
         // where
-        addWhere(buf, CTX_NAME|CTX_VALUE);
+        addWhere(sql, CTX_NAME|CTX_VALUE);
     }
     
-    protected void addDeleteWithJoins(StringBuilder buf, DBRowSet table)
+    protected void addDeleteWithJoins(DBSQLBuilder sql, DBRowSet table)
     {   // delete with joins
-        table.addSQL(buf, CTX_FULLNAME);
+        table.addSQL(sql, CTX_FULLNAME);
         // From clause
-        addFrom(buf);
+        addFrom(sql);
         // Add Where
-        addWhere(buf, CTX_DEFAULT);
+        addWhere(sql, CTX_DEFAULT);
     }
     
     // ------- Select Statement Parts -------
 
-    protected void addSelect(StringBuilder buf)
+    protected void addSelect(DBSQLBuilder sql)
     {
         // Prepares statement
-        buf.append("SELECT ");
+        sql.append("SELECT ");
         if (selectDistinct)
-            buf.append("DISTINCT ");
+            sql.append("DISTINCT ");
         // Add Select Expressions
-        addListExpr(buf, select, CTX_ALL, ", ");
+        addListExpr(sql, select, CTX_ALL, ", ");
     }
 
-    protected void addFrom(StringBuilder buf)
+    protected void addFrom(DBSQLBuilder sql)
     {
-        int originalLength = buf.length();
-        buf.append("\r\nFROM ");
+        int originalLength = sql.length();
+        sql.append("\r\nFROM ");
         // Join
         boolean sep = false;
         int whichParams = 0;
@@ -1838,22 +1838,22 @@ public abstract class DBCommand extends DBCommandExpr
                      tables .remove(join.getRightTable());
                      // Context
                      context = CTX_VALUE;
-                     buf.append( "\t" );
+                     sql.append( "\t" );
                      whichParams = 1;
                  }
                  // check
-                 addJoin(buf, join, context, whichParams);
+                 addJoin(sql, join, context, whichParams);
                  // add CRLF
                  if( i!=joins.size()-1 )
-                     buf.append("\r\n");
+                     sql.append("\r\n");
             }
             sep = true;
         }
         for (int i=0; i<tables.size(); i++)
         {
-            if (sep) buf.append(", ");
+            if (sep) sql.append(", ");
             DBRowSet t = tables.get(i); 
-            t.addSQL(buf, CTX_DEFAULT|CTX_ALIAS);
+            t.addSQL(sql, CTX_DEFAULT|CTX_ALIAS);
             // check for query
             if (t instanceof DBQuery)
             {   // Merge subquery params
@@ -1866,21 +1866,21 @@ public abstract class DBCommand extends DBCommandExpr
             String pseudoTable = getDatabase().getDbms().getSQLPhrase(DBSqlPhrase.SQL_PSEUDO_TABLE);
             if (StringUtils.isNotEmpty(pseudoTable))
             {   // add pseudo table
-                buf.append(pseudoTable);
+                sql.append(pseudoTable);
             }    
             else
             {   // remove from
-                buf.setLength(originalLength);
+                sql.reset(originalLength);
             }
         }
     }
     
-    protected void addJoin(StringBuilder buf, DBJoinExpr join, long context, int whichParams)
+    protected void addJoin(DBSQLBuilder sql, DBJoinExpr join, long context, int whichParams)
     {
         // remember insert pos
         int paramInsertPos = paramUsageCount;
         // now add the join
-        join.addSQL(buf, context);
+        join.addSQL(sql, context);
         // Merge subquery params
         Object[] subQueryParams = join.getSubqueryParams(whichParams);
         if (subQueryParams!=null)
@@ -1909,26 +1909,26 @@ public abstract class DBCommand extends DBCommandExpr
             cmdParams.add(paramUsageCount++, new DBCmdParam(null, DataType.UNKNOWN, subQueryParams[p]));
     }
 
-    protected void addWhere(StringBuilder buf, long context)
+    protected void addWhere(DBSQLBuilder sql, long context)
     {
         if (where!=null && !where.isEmpty())
         {   
-            buf.append("\r\nWHERE ");
+            sql.append("\r\nWHERE ");
             // add where expression
-            addListExpr(buf, where, context, " AND ");
+            addListExpr(sql, where, context, " AND ");
         }
     }
 
-    protected final void addWhere(StringBuilder buf)
+    protected final void addWhere(DBSQLBuilder sql)
     {
-        addWhere(buf, CTX_DEFAULT);
+        addWhere(sql, CTX_DEFAULT);
     }
     
     @Override
-    protected void addSqlExpr(StringBuilder buf, DBExpr expr, long context)
+    protected void addSqlExpr(DBSQLBuilder sql, DBExpr expr, long context)
     {
         // append
-        super.addSqlExpr(buf, expr, context);
+        super.addSqlExpr(sql, expr, context);
         // check for DBCompareExpr
         if (expr instanceof DBCompareExpr)
         {   // merge
@@ -1936,26 +1936,26 @@ public abstract class DBCommand extends DBCommandExpr
         }
     }
 
-    protected void addGrouping(StringBuilder buf)
+    protected void addGrouping(DBSQLBuilder sql)
     {
         if (groupBy!=null && !groupBy.isEmpty())
         { // Group by
-            buf.append("\r\nGROUP BY ");
-            addListExpr(buf, groupBy, CTX_DEFAULT, ", ");
+            sql.append("\r\nGROUP BY ");
+            addListExpr(sql, groupBy, CTX_DEFAULT, ", ");
         }
         if (having!=null && !having.isEmpty())
         { // Having
-            buf.append("\r\nHAVING ");
-            addListExpr(buf, having, CTX_DEFAULT, " AND ");
+            sql.append("\r\nHAVING ");
+            addListExpr(sql, having, CTX_DEFAULT, " AND ");
         }
     }
 
-    protected void addOrder(StringBuilder buf)
+    protected void addOrder(DBSQLBuilder sql)
     {
         if (orderBy!=null && !orderBy.isEmpty())
         { // order By
-            buf.append("\r\nORDER BY ");
-            addListExpr(buf, orderBy, CTX_DEFAULT, ", ");
+            sql.append("\r\nORDER BY ");
+            addListExpr(sql, orderBy, CTX_DEFAULT, ", ");
         }
     }
    
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java b/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java
index bb563738..a51c24e0 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java
@@ -99,15 +99,15 @@ public abstract class DBCommandExpr extends DBExpr
         /**
          * Creates the SQL-Command adds the select statement into the SQL-Command.
          * 
-         * @param buf the SQL-Command
+         * @param sql the SQL-Command
          * @param context the current SQL-Command context
          */
         @Override
-        public void addSQL(StringBuilder buf, long context)
+        public void addSQL(DBSQLBuilder sql, long context)
         {
-            buf.append("(");
-            buf.append(cmd.getSelect());
-            buf.append(")");
+            sql.append("(");
+            sql.append(cmd.getSelect());
+            sql.append(")");
         }
 
         /**
@@ -174,13 +174,13 @@ public abstract class DBCommandExpr extends DBExpr
         /**
          * create the SQL-Command set the expression name to the SQL-Command
          * 
-         * @param buf the SQL-Command
+         * @param sql the SQL-Command
          * @param context the current SQL-Command context
          */
         @Override
-        public void addSQL(StringBuilder buf, long context)
+        public void addSQL(DBSQLBuilder sql, long context)
         { // append UNQUALIFIED name only!
-            buf.append(expr.getName());
+            sql.append(expr.getName());
         }
 
         /**
@@ -340,7 +340,7 @@ public abstract class DBCommandExpr extends DBExpr
      * returns an SQL select command
      * @param buf the string builder to add the command to
      */
-    public abstract void getSelect(StringBuilder buf);
+    public abstract void getSelect(DBSQLBuilder sql);
 
     /**
      * returns an SQL select command for querying records.
@@ -348,7 +348,7 @@ public abstract class DBCommandExpr extends DBExpr
      */
     public final String getSelect()
     {
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = createSQLBuilder(null);
         getSelect(sql);
         return sql.toString();
     }
@@ -383,15 +383,15 @@ public abstract class DBCommandExpr extends DBExpr
     /**
      * Creates the SQL-Command.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
-        buf.append("(");
-        buf.append(getSelect());
-        buf.append(")");
+        sql.append("(");
+        sql.append(getSelect());
+        sql.append(")");
     }
 
     /**
@@ -589,7 +589,29 @@ public abstract class DBCommandExpr extends DBExpr
         }
         return getInsertInto(table, select, inscols);
     }
+    /**
+     * creates a new DBSQLBuilder 
+     * @param initalSQL
+     * @return the new DBSQLBuilder
+     */
+    protected DBMSHandler getDbms()
+    {
+        return this.getDatabase().getDbms();
+    }
 
+    /**
+     * creates a new DBSQLBuilder 
+     * @param initalSQL
+     * @return the new DBSQLBuilder
+     */
+    protected DBSQLBuilder createSQLBuilder(String initalSQL)
+    {
+        DBSQLBuilder sql = new DBSQLBuilder(getDbms());
+        if (initalSQL!=null)
+            sql.append(initalSQL);
+        return sql;
+    }
+    
     /**
      * returns column expression that is specific for to this command and detached from its source.
      */
@@ -613,31 +635,31 @@ public abstract class DBCommandExpr extends DBExpr
 
     /**
      * Internally used to build a string from a list of database expressions
-     * @param buf the sql target buffer
+     * @param sql the sql target buffer
      * @param list the list of expressions to add to the sql
      * @param context the sql command context
      * @param separator string to use as separator between list items
      */
-    protected void addListExpr(StringBuilder buf, List<? extends DBExpr> list, long context, String separator)
+    protected void addListExpr(DBSQLBuilder sql, List<? extends DBExpr> list, long context, String separator)
     {
         for (int i = 0; i < list.size(); i++)
         {   // assemble select columns
             if (i > 0)
-                buf.append(separator);
+                sql.append(separator);
             // append
-            addSqlExpr(buf, list.get(i), context);
+            addSqlExpr(sql, list.get(i), context);
         }
     }
     
     /**
      * Internally used to append a single DBExpr to a sql command builder
-     * @param buf the sql target buffer
+     * @param sql the sql target buffer
      * @param expr the expression to append
      * @param context the sql command context
      */
-    protected void addSqlExpr(StringBuilder buf, DBExpr expr, long context)
+    protected void addSqlExpr(DBSQLBuilder sql, DBExpr expr, long context)
     {
-        expr.addSQL(buf, context);
+        expr.addSQL(sql, context);
     }
     
     /**
@@ -651,8 +673,9 @@ public abstract class DBCommandExpr extends DBExpr
         if (select == null)
             throw new ObjectNotValidException(this);
         // prepare buffer
-        StringBuilder buf = new StringBuilder("INSERT INTO ");
-        table.addSQL(buf, CTX_FULLNAME);
+        DBSQLBuilder sql = new DBSQLBuilder(getDatabase().getDbms());
+        sql.append("INSERT INTO ");
+        table.addSQL(sql, CTX_FULLNAME);
         // destination columns
         if (columns != null && columns.size() > 0)
         { // Check Count
@@ -661,15 +684,15 @@ public abstract class DBCommandExpr extends DBExpr
                 throw new InvalidArgumentException("columns", "size()!=select.length");
             }
             // Append Names
-            buf.append(" (");
-            addListExpr(buf, columns, CTX_NAME, ", ");
-            buf.append(")");
+            sql.append(" (");
+            addListExpr(sql, columns, CTX_NAME, ", ");
+            sql.append(")");
         }
         // append select statement
-        buf.append("\r\n");
-        getSelect(buf);
+        sql.append("\r\n");
+        getSelect(sql);
         // done
-        return buf.toString();
+        return sql.toString();
     }
     
 }
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBDDLGenerator.java b/empire-db/src/main/java/org/apache/empire/db/DBDDLGenerator.java
index bbd0c4b8..3cb203e3 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBDDLGenerator.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBDDLGenerator.java
@@ -94,27 +94,27 @@ public abstract class DBDDLGenerator<T extends DBMSHandler>
     }
 
     // Add statements
-    protected void addCreateTableStmt(DBTable table, StringBuilder sql, DBSQLScript script)
+    protected void addCreateTableStmt(DBTable table, DBSQLBuilder sql, DBSQLScript script)
     {
         log.info("Adding create statmement for table {}.", table.getName());
         script.addStmt(sql);
     }
-    protected void addCreateIndexStmt(DBIndex index, StringBuilder sql, DBSQLScript script)
+    protected void addCreateIndexStmt(DBIndex index, DBSQLBuilder sql, DBSQLScript script)
     {
         log.info("Adding create statmement for index {}.", index.getName());
         script.addStmt(sql);
     }
-    protected void addCreateRelationStmt(DBRelation rel, StringBuilder sql, DBSQLScript script)
+    protected void addCreateRelationStmt(DBRelation rel, DBSQLBuilder sql, DBSQLScript script)
     {
         log.info("Adding create statmement for relation {}.", rel.getName());
         script.addStmt(sql);
     }
-    protected void addCreateViewStmt(DBView v, StringBuilder sql, DBSQLScript script)
+    protected void addCreateViewStmt(DBView v, DBSQLBuilder sql, DBSQLScript script)
     {
         log.info("Adding create statmement for view {}.", v.getName());
         script.addStmt(sql);
     }
-    protected void addAlterTableStmt(DBColumn col, StringBuilder sql, DBSQLScript script)
+    protected void addAlterTableStmt(DBColumn col, DBSQLBuilder sql, DBSQLScript script)
     {
         log.info("Adding alter statmement for column {}.", col.getFullName());
         script.addStmt(sql);
@@ -128,7 +128,7 @@ public abstract class DBDDLGenerator<T extends DBMSHandler>
      * @param sql the builder that we will append to
      * @return true if further column attributes may be added or false otherwise
      */
-    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, StringBuilder sql)
+    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, DBSQLBuilder sql)
     {
         switch (type)
         {
@@ -221,7 +221,7 @@ public abstract class DBDDLGenerator<T extends DBMSHandler>
      * @param alter true if altering an existing column or false otherwise
      * @param sql the sql builder object
      */
-    protected void appendColumnDesc(DBTableColumn c, boolean alter, StringBuilder sql)
+    protected void appendColumnDesc(DBTableColumn c, boolean alter, DBSQLBuilder sql)
     {
         // Append name
         c.addSQL(sql, DBExpr.CTX_NAME);
@@ -383,7 +383,7 @@ public abstract class DBDDLGenerator<T extends DBMSHandler>
      */
     protected void createTable(DBTable t, DBSQLScript script)
     {
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append("-- creating table ");
         sql.append(t.getName());
         sql.append(" --\r\n");
@@ -454,8 +454,7 @@ public abstract class DBDDLGenerator<T extends DBMSHandler>
      */
     protected void createIndex(DBTable t, DBIndex idx, DBSQLScript script)
     {
-        StringBuilder sql = new StringBuilder();
-
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         // Create Index
         sql.append((idx.getType().isUnique()) ? "CREATE UNIQUE INDEX " : "CREATE INDEX ");
         appendElementName(sql, idx.getName());
@@ -488,7 +487,7 @@ public abstract class DBDDLGenerator<T extends DBMSHandler>
         DBTable sourceTable = (DBTable) r.getReferences()[0].getSourceColumn().getRowSet();
         DBTable targetTable = (DBTable) r.getReferences()[0].getTargetColumn().getRowSet();
 
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append("-- creating foreign key constraint ");
         sql.append(r.getName());
         sql.append(" --\r\n");
@@ -536,7 +535,7 @@ public abstract class DBDDLGenerator<T extends DBMSHandler>
      */
     protected void alterTable(DBTableColumn col, DDLActionType type, DBSQLScript script)
     {
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append("ALTER TABLE ");
         col.getRowSet().addSQL(sql, DBExpr.CTX_FULLNAME);
         switch(type)
@@ -581,7 +580,7 @@ public abstract class DBDDLGenerator<T extends DBMSHandler>
         cmd.clearOrderBy();
 
         // Build String
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append( "CREATE VIEW ");
         v.addSQL(sql, DBExpr.CTX_FULLNAME);
         sql.append( " (" );
@@ -612,7 +611,7 @@ public abstract class DBDDLGenerator<T extends DBMSHandler>
         if (StringUtils.isEmpty(name))
             throw new InvalidArgumentException("name", name);
         // Create Drop Statement
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append("DROP ");
         sql.append(objType);
         sql.append(" ");
@@ -625,7 +624,7 @@ public abstract class DBDDLGenerator<T extends DBMSHandler>
         script.addStmt(sql);
     }
 
-    protected void appendElementName(StringBuilder sql, String name)
+    protected void appendElementName(DBSQLBuilder sql, String name)
     {
         dbms.appendObjectName(sql, name, null);
     }
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java b/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
index 2809a77c..adcbf6dd 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
@@ -507,32 +507,32 @@ public abstract class DBDatabase extends DBObject
      * and database link postfix (if any).
      * to the string buffer supplied
      * 
-     * @param buf the string buffer to which to append the qualified object name
+     * @param sql the SQL Builder to which to append the qualified object name
      * @param name the object's name
      * @param quoteName use quotes or not. If null detectQuoteName() is called
      */
-    public void appendQualifiedName(StringBuilder buf, String name, Boolean quoteName)
+    public void appendQualifiedName(DBSQLBuilder sql, String name, Boolean quoteName)
     {
         // Schema
         if (schema != null)
         { // Add Schema
-            buf.append(schema);
-            buf.append(".");
+            sql.append(schema);
+            sql.append(".");
         }
         // Check dbms
         if (dbms==null)
         {   // No dbms attached!
             log.warn("No dbms attached for appending qualified name {0}.", name);
-            buf.append(name);
+            sql.append(name);
             return;
         }
         // Append the name
-        dbms.appendObjectName(buf, name, quoteName);
+        dbms.appendObjectName(sql, name, quoteName);
         // Database Link
         if (linkName!=null)
         {   // Add Link
-            buf.append(dbms.getSQLPhrase(DBSqlPhrase.SQL_DATABASE_LINK));
-            buf.append(linkName);
+            sql.append(dbms.getSQLPhrase(DBSqlPhrase.SQL_DATABASE_LINK));
+            sql.append(linkName);
         }
     }
     
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBExpr.java b/empire-db/src/main/java/org/apache/empire/db/DBExpr.java
index c90193d3..885172c8 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBExpr.java
@@ -18,18 +18,8 @@
  */
 package org.apache.empire.db;
 
-import java.util.Collection;
 import java.util.Set;
 
-import org.apache.empire.commons.ObjectUtils;
-import org.apache.empire.commons.OptionEntry;
-// java
-import org.apache.empire.data.DataType;
-import org.apache.empire.dbms.DBMSHandler;
-import org.apache.empire.exceptions.InvalidArgumentException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 
 /**
  * This abstract class is the base class for all database expression classes (e.g. DBAliasExpr or DBCalsExpr)
@@ -40,7 +30,6 @@ import org.slf4j.LoggerFactory;
 public abstract class DBExpr extends DBObject
 {
     // *Deprecated* private static final long serialVersionUID = 1L;
-    private static final Logger log = LoggerFactory.getLogger(DBExpr.class);
   
     // SQL Context Flags
     public static final long CTX_DEFAULT       = 7;  // Default: FullyQualified + Value
@@ -55,10 +44,10 @@ public abstract class DBExpr extends DBObject
     /**
      * Used to build the SQL command. SQL for this expression must be appended to StringBuilder.
      * 
-     * @param buf the string buffer used to build the sql command
+     * @param sql the string buffer used to build the sql command
      * @param context context flag for this SQL-Command (see CTX_??? constants).
      */
-    public abstract void addSQL(StringBuilder buf, long context);
+    public abstract void addSQL(DBSQLBuilder sql, long context);
 
     /**
      * Internal function to obtain all DBColumnExpr-objects used by this expression. 
@@ -66,107 +55,4 @@ public abstract class DBExpr extends DBObject
      * @param list list to which all used column expressions must be added
      */
     public abstract void addReferencedColumns(Set<DBColumn> list);
-
-    /**
-     * Appends the SQL representation of a value
-     * 
-     * @param StringBuilder but the SQL builder
-     * @param dataType the DataType
-     * @param value an DBExpr object, array or a basis data type(e.g. int, String)
-     * @param context the context of the DBColumnExpr object
-     * @param arraySep the separator value
-     * @return the new SQL-Command
-     */
-    protected void addSQLValue(StringBuilder buf, DataType dataType, Object value, long context, String arraySep)
-    {
-        // it's an Object
-        if (value instanceof DBExpr)
-        {   // it's an expression
-            ((DBExpr) value).addSQL(buf, context);
-            return;
-        } 
-        // check option entry
-        if (value instanceof OptionEntry)
-        {   // option value
-            value = ((OptionEntry)value).getValue();
-        }
-        // check enum
-        if (value instanceof Enum<?>)
-        {   // check enum
-            value = ObjectUtils.getEnumValue((Enum<?>)value, dataType.isNumeric());
-        }
-        else if (value instanceof Collection<?>)
-        {   // collection 2 array
-        	value = ((Collection<?>)value).toArray();
-        }
-        // Check whether it is an array
-        if (value!=null && value.getClass().isArray())
-        {   // An Array of Objects
-            Object[] array = (Object[]) value;
-            for (int i = 0; i < array.length; i++)
-            {   // Array Separator
-                if (i > 0 && arraySep != null)
-                    buf.append(arraySep);
-                // Append Value
-                addSQLValue(buf, dataType, array[i], context, arraySep);
-            }
-            return;
-        } 
-        else
-        {   // Scalar Value from DB
-            DBMSHandler dbms = getDatabase().getDbms();
-            if (dbms==null)
-            {   // Convert to String
-                log.warn("No DBMS set for getting object value. Using default!");
-                buf.append(String.valueOf(value));
-            }
-            // Get Value Expression from dmbs
-            buf.append(dbms.getValueString(value, dataType));
-        }
-    }
-    
-    /**
-     * Expands an SQL template and adds it to the SQL command
-     * 
-     * @param StringBuilder but the SQL builder
-     * @param template the SQL template
-     * @param values an array of values to be inserted into the template
-     * @param dataType the DataType
-     * @param context the context of the DBColumnExpr object
-     * @param arraySep the separator value
-     * @return the new SQL-Command
-     */
-   protected void addSQLTemplate(StringBuilder sql, String template, Object[] values, DataType[] dataTypes, long context, String arraySep)
-    {
-        int pos = 0;
-        while (true)
-        {
-            // find begin
-            int beg = template.indexOf('{', pos);
-            if (beg < 0)
-                break;
-            // append
-            sql.append(template.substring(pos, beg));
-            // find end
-            int end = template.indexOf('}', ++beg);
-            if (end < 0)
-                throw new InvalidArgumentException("template", template);
-            // part
-            int iParam = Integer.parseInt(template.substring(beg, end));
-            if (iParam<0 || iParam>=values.length)
-                throw new InvalidArgumentException("params", values);
-            // add value
-            DataType dataType = (dataTypes.length>=iParam ? dataTypes[iParam] : dataTypes[0]);
-            addSQLValue(sql, dataType, values[iParam], context, arraySep);
-            // next
-            pos = end + 1;
-        }
-        if (pos < template.length())
-        {   // add the rest
-            sql.append(template.substring(pos));
-            // special case: Nothing added yet
-            if (pos==0 && values!=null && values.length>0)
-                log.warn("No Placeholder for found in template {}!", template);
-        }
-    }
 }
\ No newline at end of file
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBQuery.java b/empire-db/src/main/java/org/apache/empire/db/DBQuery.java
index b36b1e43..aa682a8b 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBQuery.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBQuery.java
@@ -328,20 +328,20 @@ public class DBQuery extends DBRowSet
     /**
      * Adds the select SQL Command of this object to the specified StringBuilder object.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
-        buf.append("(");
-        buf.append(cmdExpr.getSelect());
-        buf.append(")");
+        sql.append("(");
+        sql.append(cmdExpr.getSelect());
+        sql.append(")");
         // Add Alias
         if ((context & CTX_ALIAS) != 0 && alias != null)
         { // append alias
-            buf.append(" ");
-            buf.append(alias);
+            sql.append(" ");
+            sql.append(alias);
         }
     }
     
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBExpr.java b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
similarity index 61%
copy from empire-db/src/main/java/org/apache/empire/db/DBExpr.java
copy to empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
index c90193d3..2fbb3e4d 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
@@ -19,53 +19,118 @@
 package org.apache.empire.db;
 
 import java.util.Collection;
-import java.util.Set;
 
 import org.apache.empire.commons.ObjectUtils;
 import org.apache.empire.commons.OptionEntry;
-// java
 import org.apache.empire.data.DataType;
 import org.apache.empire.dbms.DBMSHandler;
+import org.apache.empire.dbms.DBSqlPhrase;
 import org.apache.empire.exceptions.InvalidArgumentException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 /**
- * This abstract class is the base class for all database expression classes (e.g. DBAliasExpr or DBCalsExpr)
- * <P>
- * 
- *
+ * DBSQLBuilder
+ * This class is used when building a single SQL-statement 
+ * @author doebele
  */
-public abstract class DBExpr extends DBObject
+public class DBSQLBuilder implements Appendable
 {
-    // *Deprecated* private static final long serialVersionUID = 1L;
-    private static final Logger log = LoggerFactory.getLogger(DBExpr.class);
-  
-    // SQL Context Flags
-    public static final long CTX_DEFAULT       = 7;  // Default: FullyQualified + Value
-    public static final long CTX_ALL           = 15; // All Flags set (except exclusions)
-
-    public static final long CTX_NAME          = 1;  // Unqualified Name
-    public static final long CTX_FULLNAME      = 2;  // Fully Qualified Name
-    public static final long CTX_VALUE         = 4;  // Value Only
-    public static final long CTX_ALIAS         = 8;  // Rename expression
-    public static final long CTX_NOPARENTHESES = 16; // No Parentheses
+    private static final Logger log = LoggerFactory.getLogger(DBSQLBuilder.class);
     
-    /**
-     * Used to build the SQL command. SQL for this expression must be appended to StringBuilder.
-     * 
-     * @param buf the string buffer used to build the sql command
-     * @param context context flag for this SQL-Command (see CTX_??? constants).
+    private final DBMSHandler dbms;
+    
+    private final StringBuilder sql = new StringBuilder(64);
+    
+    public DBSQLBuilder(DBMSHandler dbms)
+    {
+        this.dbms = dbms;
+    }
+    
+    /*
+     * getters
      */
-    public abstract void addSQL(StringBuilder buf, long context);
 
-    /**
-     * Internal function to obtain all DBColumnExpr-objects used by this expression. 
-     * 
-     * @param list list to which all used column expressions must be added
+    public DBMSHandler getDbms()
+    {
+        return dbms;
+    }
+    
+    public String getPhrase(DBSqlPhrase phrase)
+    {
+        return dbms.getSQLPhrase(phrase);
+    }
+    
+    /*
+     * special
+     */
+    public int length()
+    {
+        return sql.length();
+    }
+    
+    public void reset(int pos)
+    {
+        if (pos>sql.length())
+            throw new InvalidArgumentException("pos", pos);
+        sql.setLength(pos);
+    }
+    
+    /*
+     * appenders 
      */
-    public abstract void addReferencedColumns(Set<DBColumn> list);
+
+    @Override
+    public DBSQLBuilder append(CharSequence sqlLiteral)
+    {
+        sql.append(sqlLiteral);
+        return this;
+    }
+
+    @Override
+    public DBSQLBuilder append(CharSequence sqlLiteral, int start, int end)
+    {
+        sql.append(sqlLiteral, start, end);
+        return this;
+    }
+    
+    public DBSQLBuilder append(DBSqlPhrase phrase)
+    {
+        sql.append(dbms.getSQLPhrase(phrase));
+        return this;
+    }
+
+    @Override
+    public DBSQLBuilder append(char c)
+    {
+        sql.append(c);
+        return this;
+    }
+    
+    public DBSQLBuilder append(boolean b) {
+        sql.append(b);
+        return this;
+    }
+
+    public DBSQLBuilder append(int i) {
+        sql.append(i);
+        return this;
+    }
+
+    public DBSQLBuilder append(long l) {
+        sql.append(l);
+        return this;
+    }
+
+    public DBSQLBuilder append(float f) {
+        sql.append(f);
+        return this;
+    }
+
+    public DBSQLBuilder append(double d) {
+        sql.append(d);
+        return this;
+    }
 
     /**
      * Appends the SQL representation of a value
@@ -77,12 +142,12 @@ public abstract class DBExpr extends DBObject
      * @param arraySep the separator value
      * @return the new SQL-Command
      */
-    protected void addSQLValue(StringBuilder buf, DataType dataType, Object value, long context, String arraySep)
+    public void appendValue(DataType dataType, Object value, long context, String arraySep)
     {
         // it's an Object
         if (value instanceof DBExpr)
         {   // it's an expression
-            ((DBExpr) value).addSQL(buf, context);
+            ((DBExpr) value).addSQL(this, context);
             return;
         } 
         // check option entry
@@ -97,7 +162,7 @@ public abstract class DBExpr extends DBObject
         }
         else if (value instanceof Collection<?>)
         {   // collection 2 array
-        	value = ((Collection<?>)value).toArray();
+            value = ((Collection<?>)value).toArray();
         }
         // Check whether it is an array
         if (value!=null && value.getClass().isArray())
@@ -106,22 +171,15 @@ public abstract class DBExpr extends DBObject
             for (int i = 0; i < array.length; i++)
             {   // Array Separator
                 if (i > 0 && arraySep != null)
-                    buf.append(arraySep);
+                    sql.append(arraySep);
                 // Append Value
-                addSQLValue(buf, dataType, array[i], context, arraySep);
+                appendValue(dataType, array[i], context, arraySep);
             }
             return;
         } 
         else
-        {   // Scalar Value from DB
-            DBMSHandler dbms = getDatabase().getDbms();
-            if (dbms==null)
-            {   // Convert to String
-                log.warn("No DBMS set for getting object value. Using default!");
-                buf.append(String.valueOf(value));
-            }
-            // Get Value Expression from dmbs
-            buf.append(dbms.getValueString(value, dataType));
+        {   // Get Value Expression from dmbs
+            sql.append(dbms.getValueString(value, dataType));
         }
     }
     
@@ -136,7 +194,7 @@ public abstract class DBExpr extends DBObject
      * @param arraySep the separator value
      * @return the new SQL-Command
      */
-   protected void addSQLTemplate(StringBuilder sql, String template, Object[] values, DataType[] dataTypes, long context, String arraySep)
+    public void appendTemplate(String template, Object[] values, DataType[] dataTypes, long context, String arraySep)
     {
         int pos = 0;
         while (true)
@@ -157,7 +215,7 @@ public abstract class DBExpr extends DBObject
                 throw new InvalidArgumentException("params", values);
             // add value
             DataType dataType = (dataTypes.length>=iParam ? dataTypes[iParam] : dataTypes[0]);
-            addSQLValue(sql, dataType, values[iParam], context, arraySep);
+            appendValue(dataType, values[iParam], context, arraySep);
             // next
             pos = end + 1;
         }
@@ -169,4 +227,13 @@ public abstract class DBExpr extends DBObject
                 log.warn("No Placeholder for found in template {}!", template);
         }
     }
-}
\ No newline at end of file
+    
+    /**
+     * returns the SQL as a String 
+     */
+    @Override
+    public String toString()
+    {
+        return sql.toString();
+    }
+}
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBSQLScript.java b/empire-db/src/main/java/org/apache/empire/db/DBSQLScript.java
index 08df2684..bf21260f 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBSQLScript.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBSQLScript.java
@@ -167,11 +167,11 @@ public class DBSQLScript implements DBContextAware, Iterable<String>
      * 
      * @param sql the statement
      */
-    public final void addStmt(StringBuilder sql)
+    public final void addStmt(DBSQLBuilder sql)
     {
         addStmt(sql.toString());
         // Clear Builder
-        sql.setLength(0);
+        sql.reset(0);
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBTable.java b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
index f22a3066..651fd3e6 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBTable.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
@@ -640,22 +640,22 @@ public class DBTable extends DBRowSet implements Cloneable
     /**
      * Adds the table's name to the supplied sql command buffer.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // Append Name
         if ((context & CTX_NAME|CTX_FULLNAME)!=0)
         {   // append Qualified Name 
-            db.appendQualifiedName(buf, name, quoteName);
+            db.appendQualifiedName(sql, name, quoteName);
         }
         // Append Alias
         if ((context & CTX_ALIAS)!=0 && alias!=null)
         {    // append alias
-             buf.append(getRenameTablePhrase());
-             buf.append(getAlias());
+             sql.append(getRenameTablePhrase());
+             sql.append(getAlias());
         }
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBView.java b/empire-db/src/main/java/org/apache/empire/db/DBView.java
index 85320d16..8e199a06 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBView.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBView.java
@@ -399,22 +399,22 @@ public abstract class DBView extends DBRowSet
     /**
      * Creates the SQL-Command adds the alias name to the SQL-Command.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // Append Name
         if ((context & CTX_NAME|CTX_FULLNAME)!=0)
         {   // append Qualified Name 
-            db.appendQualifiedName(buf, name, quoteName);
+            db.appendQualifiedName(sql, name, quoteName);
         }
         // Append Alias
         if ((context & CTX_ALIAS)!=0 && alias!=null)
         {    // append alias
-             buf.append(getRenameTablePhrase());
-             buf.append(alias);
+             sql.append(getRenameTablePhrase());
+             sql.append(alias);
         }
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java
index f44ce381..6784175e 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java
@@ -27,6 +27,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.exceptions.DatabaseNotOpenException;
 import org.apache.empire.dbms.DBMSHandler;
 import org.apache.empire.exceptions.InvalidArgumentException;
@@ -269,7 +270,7 @@ public abstract class DBAbstractFuncExpr extends DBColumnExpr
     }
     */
 
-    public final void addSQL(StringBuilder sql, String template, Object[] params, long context)
+    public final void addSQL(DBSQLBuilder sql, String template, Object[] params, long context)
     {
         // parse template
         int pos=0, prev=0, len=template.length();
@@ -324,7 +325,7 @@ public abstract class DBAbstractFuncExpr extends DBColumnExpr
                         paramDataType = DataType.fromJavaType(params[iParam].getClass());
                 }
                 // append value
-                addSQLValue(sql, paramDataType, params[iParam], CTX_DEFAULT, ",");
+                sql.appendValue(paramDataType, params[iParam], CTX_DEFAULT, ",");
                 // next
                 prev = pos = end+1;
             }
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAliasExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAliasExpr.java
index e25b18da..84cd804f 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAliasExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAliasExpr.java
@@ -27,6 +27,7 @@ import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.dbms.DBMSHandler;
 import org.apache.empire.dbms.DBSqlPhrase;
 import org.w3c.dom.Element;
@@ -187,27 +188,27 @@ public class DBAliasExpr extends DBColumnExpr implements Unwrappable<DBColumnExp
     /**
      * Creates the SQL-Command adds the alias name to the SQL-Command.
      *
-     * @param buf the SQL statment
+     * @param sql the SQL statment
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     { // Append alias
         if((context & CTX_ALIAS)!=0)
         {   // Add the column expression
-            expr.addSQL(buf, context);
+            expr.addSQL(sql, context);
             // Rename
             DBMSHandler dbms = getDatabase().getDbms();
             String asExpr = dbms.getSQLPhrase(DBSqlPhrase.SQL_RENAME_COLUMN);
             if (asExpr!=null)
             {
-                buf.append(asExpr);
-                dbms.appendObjectName(buf, alias, null);
+                sql.append(asExpr);
+                dbms.appendObjectName(sql, alias, null);
             }
         } 
         else
         {
-            expr.addSQL(buf, context);
+            expr.addSQL(sql, context);
         }
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCalcExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCalcExpr.java
index e211fc68..e7311bc2 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCalcExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCalcExpr.java
@@ -29,6 +29,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.w3c.dom.Element;
 
 
@@ -207,21 +208,21 @@ public class DBCalcExpr extends DBColumnExpr
      * the specified DBColumnExpr object and value to the.
      * SQL-Command
      * 
-     * @param buf the SQL statment
+     * @param sql the SQL statment
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // Zusammenbauen
-        expr.addSQL(buf, context);
-        buf.append(op);
+        expr.addSQL(sql, context);
+        sql.append(op);
         // Special treatment for adding days to dates
         DataType type = expr.getDataType();
         if (type.isNumeric()==false && (value instanceof Number))
             type = DataType.DECIMAL;
         // append
-        addSQLValue(buf, type, value, context, op);
+        sql.appendValue(type, value, context, op);
     }
 
     @Override
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java
index e6746c46..cf904da2 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java
@@ -24,6 +24,7 @@ import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.expr.compare.DBCompareExpr;
 import org.apache.empire.xml.XMLUtil;
 import org.w3c.dom.Element;
@@ -135,7 +136,7 @@ public class DBCaseExpr extends DBColumnExpr
     }
 
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         context &= ~CTX_ALIAS; // No column aliases
         sql.append("CASE WHEN ");
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java
index 3984c53e..71d5236e 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java
@@ -25,6 +25,7 @@ import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.expr.compare.DBCompareExpr;
 import org.apache.empire.xml.XMLUtil;
 import org.w3c.dom.Element;
@@ -84,9 +85,10 @@ public class DBCaseWhenExpr extends DBColumnExpr
     public String getName()
     {
         DBCompareExpr firstCmpExpr = whenMap.keySet().iterator().next();
-        StringBuilder b = new StringBuilder("CASE_");
-        firstCmpExpr.addSQL(b, CTX_NAME);
-        return b.toString();
+        DBSQLBuilder sql = new DBSQLBuilder(getDatabase().getDbms());
+        sql.append("CASE_");
+        firstCmpExpr.addSQL(sql, CTX_NAME);
+        return sql.toString();
     }
 
     @Override
@@ -123,7 +125,7 @@ public class DBCaseWhenExpr extends DBColumnExpr
     }
 
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         context &= ~CTX_ALIAS; // No column aliases
         // append case 
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCmdResultExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCmdResultExpr.java
index 862ee172..4b480998 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCmdResultExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCmdResultExpr.java
@@ -25,6 +25,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBCommandExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.exceptions.InvalidArgumentException;
 import org.apache.empire.xml.XMLUtil;
 import org.w3c.dom.Element;
@@ -96,10 +97,10 @@ public class DBCmdResultExpr extends DBColumnExpr
     }
 
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // simply forward
-        cmdExpr.addSQL(buf, context);
+        cmdExpr.addSQL(sql, context);
     }
 
     @Override
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCoalesceExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCoalesceExpr.java
index e18decc7..8f048552 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCoalesceExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCoalesceExpr.java
@@ -25,6 +25,7 @@ import org.apache.empire.commons.Unwrappable;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.dbms.DBSqlPhrase;
 
 public class DBCoalesceExpr extends DBAbstractFuncExpr implements Unwrappable<DBColumnExpr>
@@ -107,7 +108,7 @@ public class DBCoalesceExpr extends DBAbstractFuncExpr implements Unwrappable<DB
     }
 
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // Get the template
         String template = getDbms().getSQLPhrase(DBSqlPhrase.SQL_FUNC_COALESCE);
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatExpr.java
index 1f4ef1fd..d4dcac2d 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatExpr.java
@@ -26,6 +26,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.dbms.DBSqlPhrase;
 import org.apache.empire.xml.XMLUtil;
 import org.w3c.dom.Element;
@@ -149,11 +150,11 @@ public class DBConcatExpr extends DBColumnExpr
      * a specified value sets the column with a specified value to
      * the SQL-Command.
      * 
-     * @param buf the SQL statment
+     * @param sql the SQL statment
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     { // Zusammenbauen
         String template = getDatabase().getDbms().getSQLPhrase(DBSqlPhrase.SQL_CONCAT_EXPR);
         context &= ~CTX_ALIAS; // No column aliases
@@ -161,25 +162,25 @@ public class DBConcatExpr extends DBColumnExpr
         int sep = template.indexOf('?');
         if (sep >= 0)
         {   // Complex Pattern with placeholder ? for this expression and {0} for the value
-            buf.append(template.substring(0, sep));
-            left.addSQL(buf, context);
+            sql.append(template.substring(0, sep));
+            left.addSQL(sql, context);
             // template = template.substring(sep + 1)
             int iph = template.indexOf("{0}", ++sep);
             if (iph>0)
-                buf.append(template.substring(sep, iph));
+                sql.append(template.substring(sep, iph));
             else 
-                buf.append(template.substring(sep));
+                sql.append(template.substring(sep));
             // value
-            addSQLValue(buf, getDataType(), right, context, template);
+            sql.appendValue(getDataType(), right, context, template);
             // rest
             if (iph>0)
-                buf.append(template.substring(iph+3));
+                sql.append(template.substring(iph+3));
         } 
         else
         {   // Simple Pattern without placeholders
-            left.addSQL(buf, context);
-            buf.append(template);
-            addSQLValue(buf, getDataType(), right, context, template);
+            left.addSQL(sql, context);
+            sql.append(template);
+            sql.appendValue(getDataType(), right, context, template);
         }        
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatFuncExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatFuncExpr.java
index 6638f160..1d0f1ee1 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatFuncExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatFuncExpr.java
@@ -21,6 +21,7 @@ package org.apache.empire.db.expr.column;
 import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.dbms.DBSqlPhrase;
 
 /**
@@ -110,32 +111,32 @@ public class DBConcatFuncExpr extends DBAbstractFuncExpr
     }
 
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // get template
         String template = getDatabase().getDbms().getSQLPhrase(DBSqlPhrase.SQL_FUNC_CONCAT);
         int placeholder = template.indexOf('?');
         if (placeholder>=0)
-            buf.append(template.substring(0, placeholder));
+            sql.append(template.substring(0, placeholder));
         // concat 
-        first.addSQL(buf, context);
+        first.addSQL(sql, context);
         for (int i=0; i<others.length; i++)
         {
             if (placeholder>=0)
-                buf.append(", ");
+                sql.append(", ");
             else 
-                buf.append(template);
+                sql.append(template);
             // insert separator string
             if (separator!=null && separator.length()>0)
             {   // add a separator
-                buf.append("'");
-                buf.append(separator);
-                buf.append("', ");
+                sql.append("'");
+                sql.append(separator);
+                sql.append("', ");
             }
-            others[i].addSQL(buf, context);
+            others[i].addSQL(sql, context);
         }
         if (placeholder>=0)
-            buf.append(template.substring(placeholder+1));
+            sql.append(template.substring(placeholder+1));
     }
 
 }
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConvertExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConvertExpr.java
index cbf9b6c5..84384952 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConvertExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConvertExpr.java
@@ -20,6 +20,7 @@ package org.apache.empire.db.expr.column;
 
 import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.db.DBSQLBuilder;
 
 /**
  * This class is used to convert a value to a different data type.
@@ -56,7 +57,7 @@ public class DBConvertExpr extends DBAbstractFuncExpr
     }
 
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // Set Params
         String template = getDbms().getConvertPhrase(dataType, expr.getDataType(), format);
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCountExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCountExpr.java
index 270fa811..fb657e80 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCountExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCountExpr.java
@@ -28,6 +28,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.xml.XMLUtil;
 import org.w3c.dom.Element;
 
@@ -199,7 +200,7 @@ public class DBCountExpr extends DBColumnExpr
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     { 
         sql.append("count(");
         if (column!=null)
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBDecodeExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBDecodeExpr.java
index 15741cc4..182cf74a 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBDecodeExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBDecodeExpr.java
@@ -26,7 +26,7 @@ import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBExpr;
-import org.apache.empire.dbms.DBMSHandler;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.dbms.DBSqlPhrase;
 import org.apache.empire.exceptions.InvalidArgumentException;
 
@@ -98,11 +98,10 @@ public class DBDecodeExpr extends DBAbstractFuncExpr
     }
 
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
-        DBMSHandler dbms = getDatabase().getDbms();
         // decode
-        String template = dbms.getSQLPhrase(DBSqlPhrase.SQL_FUNC_DECODE);
+        String template = sql.getPhrase(DBSqlPhrase.SQL_FUNC_DECODE);
         // parse template
         int pos=0, prev=0, len=template.length();
         while (pos<len)
@@ -131,7 +130,7 @@ public class DBDecodeExpr extends DBAbstractFuncExpr
                 if (end>=len)
                     throw new InvalidArgumentException("template", template);
                 // Add parts
-                addDecodeParts(dbms, sql);
+                addDecodeParts(sql);
                 // next
                 prev = pos = end+1;
             }
@@ -147,7 +146,7 @@ public class DBDecodeExpr extends DBAbstractFuncExpr
         }
     }
     
-    public void addDecodeParts(DBMSHandler dbms, StringBuilder sql)
+    public void addDecodeParts(DBSQLBuilder sql)
     {
         // Append parts
         for (Iterator<?> i = valueMap.keySet().iterator(); i.hasNext();)
@@ -155,21 +154,21 @@ public class DBDecodeExpr extends DBAbstractFuncExpr
             Object key = i.next();
             Object val = valueMap.get(key);
 
-            sql.append(dbms.getSQLPhrase(DBSqlPhrase.SQL_FUNC_DECODE_SEP));
+            sql.append(DBSqlPhrase.SQL_FUNC_DECODE_SEP);
             
             Object[] keyVal = new Object[] { key, val };
             DataType[] dataTypes = new DataType[] { expr.getDataType(), this.getDataType() };
             
-            String part = dbms.getSQLPhrase(DBSqlPhrase.SQL_FUNC_DECODE_PART);
-            addSQLTemplate(sql, part, keyVal, dataTypes, CTX_DEFAULT, "");
+            String part = sql.getPhrase(DBSqlPhrase.SQL_FUNC_DECODE_PART);
+            sql.appendTemplate(part, keyVal, dataTypes, CTX_DEFAULT, "");
         }
         // Generate other
         if (elseExpr != null)
         { // Else
-            sql.append(dbms.getSQLPhrase(DBSqlPhrase.SQL_FUNC_DECODE_SEP));
+            sql.append(DBSqlPhrase.SQL_FUNC_DECODE_SEP);
             // else
-            String other = dbms.getSQLPhrase(DBSqlPhrase.SQL_FUNC_DECODE_ELSE);
-            addSQLTemplate(sql, other, new Object[] { elseExpr }, new DataType[] { getDataType() }, CTX_DEFAULT, "");
+            String other = sql.getPhrase(DBSqlPhrase.SQL_FUNC_DECODE_ELSE);
+            sql.appendTemplate(other, new Object[] { elseExpr }, new DataType[] { getDataType() }, CTX_DEFAULT, "");
         }
     }
     
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBFuncExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBFuncExpr.java
index ccf5ee5f..5084a3d3 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBFuncExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBFuncExpr.java
@@ -27,6 +27,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.dbms.DBSqlPhrase;
 import org.apache.empire.exceptions.InvalidArgumentException;
 import org.apache.empire.exceptions.NotSupportedException;
@@ -164,7 +165,7 @@ public class DBFuncExpr extends DBAbstractFuncExpr
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {   // Get Template
         if (this.template==null)
         {   this.template = getDbms().getSQLPhrase(phrase);
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBParenthesisExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBParenthesisExpr.java
index df6cce39..c5ca6a7a 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBParenthesisExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBParenthesisExpr.java
@@ -25,6 +25,7 @@ import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.w3c.dom.Element;
 
 /**
@@ -179,15 +180,15 @@ public class DBParenthesisExpr extends DBColumnExpr implements Unwrappable<DBCol
     /**
      * Creates the SQL-Command adds the alias name to the SQL-Command.
      *
-     * @param buf the SQL statment
+     * @param sql the SQL statment
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {   // Append alias
-        buf.append("(");
-        wrapped.addSQL(buf, context); // |CTX_NOPARENTHESES
-        buf.append(")");
+        sql.append("(");
+        wrapped.addSQL(sql, context); // |CTX_NOPARENTHESES
+        sql.append(")");
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBScalarExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBScalarExpr.java
index 3f03b781..45db3d81 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBScalarExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBScalarExpr.java
@@ -26,6 +26,7 @@ import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.xml.XMLUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -219,12 +220,12 @@ public class DBScalarExpr extends DBColumnExpr
     /**
      * Creates the SQL-Command.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
-        addSQLTemplate(sql, template, params, new DataType[] { dataType }, CTX_DEFAULT, ",");
+        sql.appendTemplate(template, params, new DataType[] { dataType }, CTX_DEFAULT, ",");
     }
 }
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java
index 5f502e64..18f60eb0 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java
@@ -28,6 +28,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.dbms.DBMSHandler;
 import org.apache.empire.xml.XMLUtil;
 import org.w3c.dom.Element;
@@ -227,15 +228,15 @@ public class DBValueExpr extends DBColumnExpr
     /**
      * Creates the SQL-Command.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         if (value instanceof DBExpr)
         {   // its an expression
-            ((DBExpr)value).addSQL(buf, context);
+            ((DBExpr)value).addSQL(sql, context);
         }
         else
         {   // unpack
@@ -246,7 +247,7 @@ public class DBValueExpr extends DBColumnExpr
             // convert value to sql literal
             DBMSHandler dbms = db.getDbms();
             String text = (dbms!=null) ? dbms.getValueString(dataValue, dataType) : ObjectUtils.getString(dataValue); 
-            buf.append(text);
+            sql.append(text);
         }
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBVarArgsFuncExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBVarArgsFuncExpr.java
index 4c57c173..e05a1c06 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBVarArgsFuncExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBVarArgsFuncExpr.java
@@ -25,6 +25,7 @@ import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.exceptions.InvalidArgumentException;
 import org.apache.empire.xml.XMLUtil;
 import org.w3c.dom.Element;
@@ -131,29 +132,27 @@ public class DBVarArgsFuncExpr extends DBColumnExpr
     }
 
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
-        StringBuilder b = new StringBuilder();
-        for (int i=0; i<cols.length; i++)
-        {
-            if (i>0)
-                b.append(", ");
-            // add SQL
-            DBColumnExpr col = cols[i];
-            col.addSQL(b, CTX_DEFAULT);
-        }    
         // Get Template
-        String prefix  = template;
-        String postfix = "";
+        String prefix = template;
+        String suffix = "";
         int sep = template.indexOf("?");
         if (sep >= 0)
-        {   prefix  = template.substring(0, sep);
-            postfix = template.substring(sep + 1);
+        {   prefix = template.substring(0, sep);
+            suffix = template.substring(sep + 1);
         } 
         // append
         sql.append(prefix);
-        sql.append(b.toString());
-        sql.append(postfix);
+        for (int i=0; i<cols.length; i++)
+        {   // separator
+            if (i>0)
+                sql.append(", ");
+            // add SQL
+            DBColumnExpr col = cols[i];
+            col.addSQL(sql, CTX_DEFAULT);
+        }    
+        sql.append(suffix);
     }
 
     @Override
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareAndOrExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareAndOrExpr.java
index dca8d567..0a719d2c 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareAndOrExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareAndOrExpr.java
@@ -24,6 +24,7 @@ import org.apache.empire.commons.ObjectUtils;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 
 
 /**
@@ -118,46 +119,46 @@ public class DBCompareAndOrExpr extends DBCompareExpr
      * Creates the SQL-Command sets the specified compare value 
      * (the varible boolOP) between the two DBCompareExpr objects.
      * 
-     * @param buf the SQL statment
+     * @param sql the SQL statment
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // Name or Value Only ?
         if ((context & CTX_NAME )==0 ||
             (context & CTX_VALUE)==0)
         { // add both values separated by ","
-            left.addSQL(buf, context);
-            buf.append(",");
-            right.addSQL(buf, context);
+            left.addSQL(sql, context);
+            sql.append(",");
+            right.addSQL(sql, context);
             return;
         }
         // Parenthesis
         boolean parenthesis = ((context & CTX_NOPARENTHESES) == 0) && or;
         boolean nested = ((left instanceof DBCompareAndOrExpr) && ((DBCompareAndOrExpr)left).or==false);
         if (parenthesis)
-            buf.append("(");
+            sql.append("(");
         if (parenthesis && nested)
-            buf.append("(");
+            sql.append("(");
         // the left expression
-        left.addSQL(buf, context);
+        left.addSQL(sql, context);
         // Parenthesis
         if (parenthesis && nested)
-            buf.append(")");
+            sql.append(")");
         // Combine operator
-        buf.append((or ? " OR " : " AND "));
+        sql.append((or ? " OR " : " AND "));
         // Parenthesis
         nested = ((right instanceof DBCompareAndOrExpr) && ((DBCompareAndOrExpr)right).or==false);
         if (parenthesis && nested)
-            buf.append("(");
+            sql.append("(");
         // the right expression
-        right.addSQL(buf, context);
+        right.addSQL(sql, context);
         if (parenthesis && nested)
-            buf.append(")");
+            sql.append(")");
         // Parenthesis
         if (parenthesis)
-            buf.append(")");
+            sql.append(")");
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareColExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareColExpr.java
index 39f8fcc4..ef3ca857 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareColExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareColExpr.java
@@ -30,6 +30,7 @@ import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBCommandExpr;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.expr.column.DBAliasExpr;
 
 
@@ -177,10 +178,10 @@ public class DBCompareColExpr extends DBCompareExpr
     /**
      * Add the comparison operator and value to the SQL-Command.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the comparative context e.g. (CMP_EQUAL, CMP_SMALLER)
      */
-    public void addCompareExpr(StringBuilder buf, long context)
+    public void addCompareExpr(DBSQLBuilder sql, long context)
     {   // Assemble expression
         DBCmpType op = cmpop;
         if (ObjectUtils.isEmpty(value))
@@ -208,85 +209,85 @@ public class DBCompareColExpr extends DBCompareExpr
         switch (op)
         {
             case EQUAL:
-                buf.append("=");
+                sql.append("=");
                 break;
             case NOTEQUAL:
-                buf.append("<>");
+                sql.append("<>");
                 break;
             case LESSTHAN:
-                buf.append("<");
+                sql.append("<");
                 break;
             case MOREOREQUAL:
-                buf.append(">=");
+                sql.append(">=");
                 break;
             case GREATERTHAN:
-                buf.append(">");
+                sql.append(">");
                 break;
             case LESSOREQUAL:
-                buf.append("<=");
+                sql.append("<=");
                 break;
             case LIKE:
-                buf.append(" LIKE ");
+                sql.append(" LIKE ");
                 break;
             case NOTLIKE:
-                buf.append(" NOT LIKE ");
+                sql.append(" NOT LIKE ");
                 break;
             case NULL:
-                buf.append(" IS NULL");
+                sql.append(" IS NULL");
                 return;
             case NOTNULL:
-                buf.append(" IS NOT NULL");
+                sql.append(" IS NOT NULL");
                 return;
             case BETWEEN:
-                buf.append(" BETWEEN ");
+                sql.append(" BETWEEN ");
                 break;
             case NOTBETWEEN:
-                buf.append(" NOT BETWEEN ");
+                sql.append(" NOT BETWEEN ");
                 break;
             case IN:
-                buf.append(" IN (");
+                sql.append(" IN (");
                 suffix = ")";
                 break;
             case NOTIN:
-                buf.append(" NOT IN (");
+                sql.append(" NOT IN (");
                 suffix = ")";
                 break;
             default:
                 // NONE
-                buf.append(" ");
+                sql.append(" ");
         }
         // append value
-        addSQLValue(buf, expr.getDataType(), value, context, arraySep);
+        sql.appendValue(expr.getDataType(), value, context, arraySep);
         // append suffix
         if (suffix != null)
-            buf.append(suffix);
+            sql.append(suffix);
     }
 
     /**
      * Creates the SQL-Command.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // Name Only ?
         if ((context & CTX_VALUE) == 0)
         {
-            expr.addSQL(buf, context);
+            expr.addSQL(sql, context);
             return;
         }
         // Value Only ?
         if ((context & CTX_NAME) == 0)
         {   // add SQL
-            addSQLValue(buf, expr.getDataType(), value, context, null);
+            sql.appendValue(expr.getDataType(), value, context, null);
             return;
         }
         // Add Compare Expression
-        expr.addSQL(buf, context);
+        expr.addSQL(sql, context);
         // Add Comparison Value
-        addCompareExpr(buf, context);
+        addCompareExpr(sql, context);
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareNotExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareNotExpr.java
index 87977a35..e5cdeede 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareNotExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareNotExpr.java
@@ -24,6 +24,7 @@ import org.apache.empire.commons.ObjectUtils;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 
 
 /**
@@ -105,22 +106,22 @@ public class DBCompareNotExpr extends DBCompareExpr
      * Creates the SQL-Command sets the specified compare value
      * (the varible boolOP) between the two DBCompareExpr objects.
      * 
-     * @param buf the SQL statment
+     * @param sql the SQL statment
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // Name Only ?
         if ((context & CTX_VALUE)==0)
         { // add both values separated by ","
-            expr.addSQL(buf, context);
+            expr.addSQL(sql, context);
             return;
         }
         // add SQL
-        buf .append(" NOT(");
-        expr.addSQL(buf, context);
-        buf .append(" )");
+        sql .append(" NOT(");
+        expr.addSQL(sql, context);
+        sql .append(" )");
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareParenthesisExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareParenthesisExpr.java
index 72156628..41dfc9f0 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareParenthesisExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareParenthesisExpr.java
@@ -24,6 +24,7 @@ import org.apache.empire.commons.Unwrappable;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 
 /**
  * This class wraps an existing compare expression with parenthesis.
@@ -83,11 +84,11 @@ public class DBCompareParenthesisExpr extends DBCompareExpr implements Unwrappab
     }
 
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
-        buf.append("(");
-        wrapped.addSQL(buf, context|CTX_NOPARENTHESES);
-        buf.append(")");
+        sql.append("(");
+        wrapped.addSQL(sql, context|CTX_NOPARENTHESES);
+        sql.append(")");
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBExistsExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBExistsExpr.java
index de033fec..76bb52e3 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBExistsExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBExistsExpr.java
@@ -24,6 +24,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBCommandExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -111,11 +112,11 @@ public class DBExistsExpr extends DBCompareExpr
     /**
      * Creates the SQL-Command.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the current SQL-Command context (CTX_DEFAULT, CTX_SELECT, CTX_NAME, CTX_VALUE)
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // Name Only ?
         if ((context & CTX_VALUE) == 0)
@@ -129,24 +130,24 @@ public class DBExistsExpr extends DBCompareExpr
             log.warn("cannot add value only of exits expression");
             return;
         }
-        buf.append(" exists (");
-        cmd.getSelect(buf);
+        sql.append(" exists (");
+        cmd.getSelect(sql);
 
         if (compareExpr != null)
         {
             if (cmd instanceof DBCommand && ((DBCommand) cmd).getWhereConstraints() == null)
             {
-                buf.append(" where ");
+                sql.append(" where ");
             } 
             else
             {
-                buf.append(" and ");
+                sql.append(" and ");
             }
-            buf.append("(");
-            compareExpr.addSQL(buf, context);
-            buf.append(") ");
+            sql.append("(");
+            compareExpr.addSQL(sql, context);
+            sql.append(") ");
         }
-        buf.append(") ");
+        sql.append(") ");
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBColumnJoinExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBColumnJoinExpr.java
index 273415bd..9904cb8d 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBColumnJoinExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBColumnJoinExpr.java
@@ -28,6 +28,7 @@ import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBJoinType;
 import org.apache.empire.db.DBQuery;
 import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.expr.compare.DBCompareExpr;
 import org.apache.empire.exceptions.InvalidPropertyException;
 
@@ -236,32 +237,32 @@ public class DBColumnJoinExpr extends DBJoinExpr
 
     /** Not allowed, this operation have to be done in the DBCommand object. */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // left 
         if ((context & CTX_NAME) != 0)
-            getLeftTable().addSQL(buf, CTX_DEFAULT | CTX_ALIAS);
+            getLeftTable().addSQL(sql, CTX_DEFAULT | CTX_ALIAS);
         if ((context & CTX_VALUE) != 0)
         { // Join Type
             switch(type)
             {
-                case LEFT:  buf.append(" LEFT JOIN ");break;
-                case INNER: buf.append(" INNER JOIN ");break;
-                case RIGHT: buf.append(" RIGHT JOIN ");break;
-                case FULL:  buf.append(" FULL JOIN ");break;
-                default:    buf.append(" JOIN "); // should not come here!
+                case LEFT:  sql.append(" LEFT JOIN ");break;
+                case INNER: sql.append(" INNER JOIN ");break;
+                case RIGHT: sql.append(" RIGHT JOIN ");break;
+                case FULL:  sql.append(" FULL JOIN ");break;
+                default:    sql.append(" JOIN "); // should not come here!
             }
-            getRightTable().addSQL(buf, CTX_DEFAULT | CTX_ALIAS);
+            getRightTable().addSQL(sql, CTX_DEFAULT | CTX_ALIAS);
             // compare equal
-            buf.append(" ON ");
-            right.addSQL(buf, CTX_DEFAULT);
-            buf.append(" = ");
-            left.addSQL(buf, CTX_DEFAULT);
+            sql.append(" ON ");
+            right.addSQL(sql, CTX_DEFAULT);
+            sql.append(" = ");
+            left.addSQL(sql, CTX_DEFAULT);
             // Compare Expression
             if (compExpr != null)
             {
-                buf.append(" AND ");
-                compExpr.addSQL(buf, CTX_DEFAULT);
+                sql.append(" AND ");
+                compExpr.addSQL(sql, CTX_DEFAULT);
             }
         }
     }
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCompareJoinExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCompareJoinExpr.java
index d551c43f..2779ee17 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCompareJoinExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCompareJoinExpr.java
@@ -23,6 +23,7 @@ import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBJoinType;
 import org.apache.empire.db.DBQuery;
 import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.expr.compare.DBCompareAndOrExpr;
 import org.apache.empire.db.expr.compare.DBCompareColExpr;
 import org.apache.empire.db.expr.compare.DBCompareExpr;
@@ -104,29 +105,29 @@ public class DBCompareJoinExpr extends DBColumnJoinExpr
     }
 
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // left 
         if ((context & CTX_NAME) != 0)
-            getLeftTable().addSQL(buf, CTX_DEFAULT | CTX_ALIAS);
+            getLeftTable().addSQL(sql, CTX_DEFAULT | CTX_ALIAS);
         if ((context & CTX_VALUE) != 0)
         { // Join Type
             switch(type)
             {
-                case LEFT:  buf.append(" LEFT JOIN ");break;
-                case INNER: buf.append(" INNER JOIN ");break;
-                case RIGHT: buf.append(" RIGHT JOIN ");break;
-                default:    buf.append(" JOIN "); // should not come here!
+                case LEFT:  sql.append(" LEFT JOIN ");break;
+                case INNER: sql.append(" INNER JOIN ");break;
+                case RIGHT: sql.append(" RIGHT JOIN ");break;
+                default:    sql.append(" JOIN "); // should not come here!
             }
-            getRightTable().addSQL(buf, CTX_DEFAULT | CTX_ALIAS);
+            getRightTable().addSQL(sql, CTX_DEFAULT | CTX_ALIAS);
             // compare equal
-            buf.append(" ON ");
-            cmp.addSQL(buf, CTX_DEFAULT);
+            sql.append(" ON ");
+            cmp.addSQL(sql, CTX_DEFAULT);
             // Compare Expression
             if (compExpr != null)
             {
-                buf.append(" AND ");
-                compExpr.addSQL(buf, CTX_DEFAULT);
+                sql.append(" AND ");
+                compExpr.addSQL(sql, CTX_DEFAULT);
             }
         }
     }
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCrossJoinExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCrossJoinExpr.java
index 6ee9d314..cd494565 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCrossJoinExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBCrossJoinExpr.java
@@ -27,6 +27,7 @@ import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBJoinType;
 import org.apache.empire.db.DBQuery;
 import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBSQLBuilder;
 
 /**
  * This class is used for building a join expression of an SQL statement.
@@ -155,14 +156,14 @@ public class DBCrossJoinExpr extends DBJoinExpr
 
     /** Not allowed, this operation have to be done in the DBCommand object. */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         if ((context & CTX_NAME) != 0)
-            left.addSQL(buf, CTX_DEFAULT | CTX_ALIAS);
+            left.addSQL(sql, CTX_DEFAULT | CTX_ALIAS);
         if ((context & CTX_VALUE) != 0)
         { // Join Type
-            buf.append(" CROSS JOIN ");
-            right.addSQL(buf, CTX_DEFAULT | CTX_ALIAS);
+            sql.append(" CROSS JOIN ");
+            right.addSQL(sql, CTX_DEFAULT | CTX_ALIAS);
         }
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/order/DBOrderByExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/order/DBOrderByExpr.java
index cdff70c7..4ddcad20 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/order/DBOrderByExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/order/DBOrderByExpr.java
@@ -22,6 +22,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 
 import java.util.Set;
 
@@ -82,17 +83,17 @@ public class DBOrderByExpr extends DBExpr
     /**
      * Adds a column expression to the orderBy clause followed by the desc keyword if the order should be descending 
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {   // Set SQL-Order By
-        expr.addSQL(buf, context);
+        expr.addSQL(sql, context);
         // only need to add DESC as default is ASC
         if (desc)
         {
-            buf.append(" DESC");
+            sql.append(" DESC");
         }
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/set/DBSetExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/set/DBSetExpr.java
index 7cdc1835..f3258d9e 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/set/DBSetExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/set/DBSetExpr.java
@@ -27,6 +27,7 @@ import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBSQLBuilder;
 
 
 /**
@@ -132,13 +133,13 @@ public class DBSetExpr extends DBExpr
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         if ((context & CTX_NAME) != 0)
             column.addSQL(sql, CTX_NAME);
         if ((context & CTX_NAME) != 0 && (context & CTX_VALUE) != 0)
             sql.append("=");
         if ((context & CTX_VALUE) != 0)
-            addSQLValue(sql, column.getDataType(), value, context, "+");
+            sql.appendValue(column.getDataType(), value, context, "+");
     }
 }
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandler.java b/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandler.java
index e3b7cd4a..cc4105a7 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandler.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandler.java
@@ -31,6 +31,7 @@ import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBObject;
 import org.apache.empire.db.DBRelation;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTableColumn;
 import org.apache.empire.db.validation.DBModelChecker;
@@ -87,7 +88,7 @@ public interface DBMSHandler
      * @param name the name of the object (table, view or column)
      * @param useQuotes use quotes or not. When null is passed then detectQuoteName() is called
      */
-    void appendObjectName(StringBuilder sql, String name, Boolean useQuotes);
+    void appendObjectName(DBSQLBuilder sql, String name, Boolean useQuotes);
     
     /**
      * Returns an sql phrase template for this database system.<br>
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java b/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java
index fc5d358c..f5314d8d 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java
@@ -50,6 +50,7 @@ import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBRelation;
 import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
@@ -246,7 +247,8 @@ public abstract class DBMSHandlerBase implements DBMSHandler
         String schema   = db.getSchema();
         String linkName = db.getLinkName();
         // build the statement
-        StringBuilder sql = new StringBuilder("SELECT count(*) from ");
+        DBSQLBuilder sql = new DBSQLBuilder(this);
+        sql.append("SELECT count(*) from ");
         if (schema != null)
         {   // Add Schema
             sql.append(schema);
@@ -355,7 +357,7 @@ public abstract class DBMSHandlerBase implements DBMSHandler
      * @param useQuotes use quotes or not
      */
     @Override
-    public void appendObjectName(StringBuilder sql, String name, Boolean useQuotes)
+    public void appendObjectName(DBSQLBuilder sql, String name, Boolean useQuotes)
     {
         if (useQuotes==null)
             useQuotes = detectQuoteName(name);
@@ -1057,10 +1059,14 @@ public abstract class DBMSHandlerBase implements DBMSHandler
      */
     protected String getSQLTextString(DataType type, Object value)
     {
-        StringBuilder valBuf = new StringBuilder();
+        if (value==null)
+            return getSQLPhrase(DBSqlPhrase.SQL_NULL);
+        // text
+        String text = value.toString();
+        StringBuilder valBuf = new StringBuilder(text.length()+2);
         valBuf.append("'");
         if (DBDatabase.EMPTY_STRING.equals(value)==false)
-            appendSQLTextValue(valBuf, value.toString());
+            appendSQLTextValue(valBuf, text);
         valBuf.append("'");
         return valBuf.toString();
     }
@@ -1068,7 +1074,7 @@ public abstract class DBMSHandlerBase implements DBMSHandler
     /** 
      * this helper function doubles up single quotes for SQL 
      */
-    protected void appendSQLTextValue(StringBuilder buf, String value)
+    protected void appendSQLTextValue(StringBuilder sql, String value)
     {
         if (value.indexOf('\'') >= 0)
         { // a routine to double up single quotes for SQL
@@ -1076,14 +1082,14 @@ public abstract class DBMSHandlerBase implements DBMSHandler
             for (int i = 0; i < len; i++)
             {
                 if (value.charAt(i) == '\'')
-                    buf.append("''");
+                    sql.append("''");
                 else
-                    buf.append(value.charAt(i));
+                    sql.append(value.charAt(i));
             }
         } 
         else
         {
-            buf.append(value);
+            sql.append(value);
         }
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/derby/DerbyDDLGenerator.java b/empire-db/src/main/java/org/apache/empire/dbms/derby/DerbyDDLGenerator.java
index 261b4ec7..352c37e8 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/derby/DerbyDDLGenerator.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/derby/DerbyDDLGenerator.java
@@ -21,6 +21,7 @@ package org.apache.empire.dbms.derby;
 import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBDDLGenerator;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBTableColumn;
 
 public class DerbyDDLGenerator extends DBDDLGenerator<DBMSHandlerDerby>
@@ -41,7 +42,7 @@ public class DerbyDDLGenerator extends DBDDLGenerator<DBMSHandlerDerby>
     }
 
     @Override
-    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, StringBuilder sql)
+    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, DBSQLBuilder sql)
     {
         switch (type)
         {
@@ -60,7 +61,7 @@ public class DerbyDDLGenerator extends DBDDLGenerator<DBMSHandlerDerby>
     }
     
     @Override
-    protected void appendColumnDesc(DBTableColumn c, boolean alter, StringBuilder sql)
+    protected void appendColumnDesc(DBTableColumn c, boolean alter, DBSQLBuilder sql)
     {
         // Append name
         c.addSQL(sql, DBExpr.CTX_NAME);
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java b/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java
index 79c6f3e9..61479d29 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java
@@ -26,15 +26,16 @@ import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBDDLGenerator;
 import org.apache.empire.db.DBDDLGenerator.DDLActionType;
-import org.apache.empire.dbms.DBMSHandler;
-import org.apache.empire.dbms.DBMSHandlerBase;
-import org.apache.empire.dbms.DBMSFeature;
-import org.apache.empire.dbms.DBSqlPhrase;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBObject;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
+import org.apache.empire.dbms.DBMSFeature;
+import org.apache.empire.dbms.DBMSHandler;
+import org.apache.empire.dbms.DBMSHandlerBase;
+import org.apache.empire.dbms.DBSqlPhrase;
 import org.apache.empire.exceptions.InvalidArgumentException;
 import org.apache.empire.exceptions.NotSupportedException;
 import org.slf4j.Logger;
@@ -93,17 +94,17 @@ public class DBMSHandlerH2 extends DBMSHandlerBase
 	    }
         
         @Override
-        public void getSelect(StringBuilder buf)
+        public void getSelect(DBSQLBuilder sql)
         {   // Prepares statement
-        	super.getSelect(buf);
+        	super.getSelect(sql);
             // add limit and offset
             if (limitRows>=0)
-            {   buf.append("\r\nLIMIT ");
-                buf.append(String.valueOf(limitRows));
+            {   sql.append("\r\nLIMIT ");
+                sql.append(String.valueOf(limitRows));
                 // Offset
                 if (skipRows>0) 
-                {   buf.append(" OFFSET ");
-                    buf.append(String.valueOf(skipRows));
+                {   sql.append(" OFFSET ");
+                    sql.append(String.valueOf(skipRows));
                 }    
             }
         }
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/h2/H2DDLGenerator.java b/empire-db/src/main/java/org/apache/empire/dbms/h2/H2DDLGenerator.java
index b3978e77..9439ab7f 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/h2/H2DDLGenerator.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/h2/H2DDLGenerator.java
@@ -20,6 +20,7 @@ package org.apache.empire.dbms.h2;
 
 import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBDDLGenerator;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBTableColumn;
 
 public class H2DDLGenerator extends DBDDLGenerator<DBMSHandlerH2>
@@ -41,7 +42,7 @@ public class H2DDLGenerator extends DBDDLGenerator<DBMSHandlerH2>
     }
 
     @Override
-    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, StringBuilder sql)
+    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, DBSQLBuilder sql)
     {
         switch (type)
         {
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBCommandHSql.java b/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBCommandHSql.java
index 89f435da..4d071547 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBCommandHSql.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBCommandHSql.java
@@ -26,6 +26,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.exceptions.NoPrimaryKeyException;
 import org.apache.empire.db.expr.column.DBAliasExpr;
 import org.apache.empire.db.expr.column.DBValueExpr;
@@ -74,34 +75,34 @@ public class DBCommandHSql extends DBCommand
     }
         
     @Override
-    public void getSelect(StringBuilder buf)
+    public void getSelect(DBSQLBuilder sql)
     {   // call base class
-        super.getSelect(buf);
+        super.getSelect(sql);
         // add limit and offset
         if (limitRows>=0)
-        {   buf.append("\r\nLIMIT ");
-            buf.append(String.valueOf(limitRows));
+        {   sql.append("\r\nLIMIT ");
+            sql.append(String.valueOf(limitRows));
             // Offset
             if (skipRows>0) 
-            {   buf.append(" OFFSET ");
-                buf.append(String.valueOf(skipRows));
+            {   sql.append(" OFFSET ");
+                sql.append(String.valueOf(skipRows));
             }    
         }
     }
 
     @Override
-    protected void addUpdateWithJoins(StringBuilder buf, DBRowSet table)
+    protected void addUpdateWithJoins(DBSQLBuilder sql, DBRowSet table)
     {
         // The update table
         DBColumn[] keyColumns = table.getKeyColumns();
         if (keyColumns==null || keyColumns.length==0)
             throw new NoPrimaryKeyException(table);
         // Generate Merge expression
-        buf.setLength(0);
-        buf.append("MERGE INTO ");
-        table.addSQL(buf, CTX_FULLNAME|CTX_ALIAS);
+        sql.reset(0);
+        sql.append("MERGE INTO ");
+        table.addSQL(sql, CTX_FULLNAME|CTX_ALIAS);
         // Using
-        buf.append("\r\nUSING (");
+        sql.append("\r\nUSING (");
         // Add set expressions
         List<DBColumnExpr> using = new ArrayList<DBColumnExpr>();
         // Add key columns
@@ -132,28 +133,28 @@ public class DBCommandHSql extends DBCommand
             }
         }
         // Add select
-        buf.append("SELECT ");
-        addListExpr(buf, using, CTX_ALL, ", ");
+        sql.append("SELECT ");
+        addListExpr(sql, using, CTX_ALL, ", ");
         // From clause
-        addFrom(buf);
+        addFrom(sql);
         // Add Where
-        addWhere(buf);
+        addWhere(sql);
         // Add Grouping
-        addGrouping(buf);
+        addGrouping(sql);
         // on
-        buf.append(") q0\r\nON (");
+        sql.append(") q0\r\nON (");
         for (DBColumn col : keyColumns)
         {   // compare 
-            buf.append(" q0.");
-            col.addSQL(buf, CTX_NAME);
-            buf.append("=");
-            buf.append(table.getAlias());
-            buf.append(".");
-            col.addSQL(buf, CTX_NAME);
+            sql.append(" q0.");
+            col.addSQL(sql, CTX_NAME);
+            sql.append("=");
+            sql.append(table.getAlias());
+            sql.append(".");
+            col.addSQL(sql, CTX_NAME);
         }
         // Set Expressions
-        buf.append(")\r\nWHEN MATCHED THEN UPDATE ");
-        buf.append("\r\nSET ");
-        addListExpr(buf, mergeSet, CTX_DEFAULT, ", ");
+        sql.append(")\r\nWHEN MATCHED THEN UPDATE ");
+        sql.append("\r\nSET ");
+        addListExpr(sql, mergeSet, CTX_DEFAULT, ", ");
     }
 }
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java b/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java
index 0acbef4b..22bb1bf8 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java
@@ -29,6 +29,7 @@ import org.apache.empire.db.DBDDLGenerator;
 import org.apache.empire.db.DBDDLGenerator.DDLActionType;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBObject;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTableColumn;
 import org.apache.empire.db.exceptions.QueryNoResultException;
@@ -234,7 +235,7 @@ public class DBMSHandlerHSql extends DBMSHandlerBase
     @Override
     public Object getNextSequenceValue(DBDatabase db, String seqName, int minValue, Connection conn)
     { 	//Use Oracle Sequences
-        StringBuilder sql = new StringBuilder(80);
+        DBSQLBuilder sql = new DBSQLBuilder(this);
         sql.append("SELECT ");
         sql.append("NEXT VALUE FOR ");
         db.appendQualifiedName(sql, seqName, null);
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/hsql/HSqlDDLGenerator.java b/empire-db/src/main/java/org/apache/empire/dbms/hsql/HSqlDDLGenerator.java
index a87387e8..d5c2eb72 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/hsql/HSqlDDLGenerator.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/hsql/HSqlDDLGenerator.java
@@ -23,6 +23,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBDDLGenerator;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBObject;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
@@ -108,7 +109,7 @@ public class HSqlDDLGenerator extends DBDDLGenerator<DBMSHandlerHSql>
     {
         String seqName = dbms.getColumnSequenceName(column);
         // createSQL
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append("-- creating sequence for column ");
         sql.append(column.toString());
         sql.append(" --\r\n");
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java b/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java
index 0afb4aeb..eb07418d 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java
@@ -33,13 +33,14 @@ import org.apache.empire.db.DBDDLGenerator.DDLActionType;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBObject;
 import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
 import org.apache.empire.db.exceptions.EmpireSQLException;
+import org.apache.empire.dbms.DBMSFeature;
 import org.apache.empire.dbms.DBMSHandler;
 import org.apache.empire.dbms.DBMSHandlerBase;
-import org.apache.empire.dbms.DBMSFeature;
 import org.apache.empire.dbms.DBSqlPhrase;
 import org.apache.empire.exceptions.NotSupportedException;
 import org.slf4j.Logger;
@@ -93,17 +94,17 @@ public class DBMSHandlerMySQL extends DBMSHandlerBase
         }
         
         @Override
-        public void getSelect(StringBuilder buf)
+        public void getSelect(DBSQLBuilder sql)
         {   // call base class
-            super.getSelect(buf);
+            super.getSelect(sql);
             // add limit and offset
             if (limit>=0)
-            {   buf.append("\r\nLIMIT ");
-                buf.append(String.valueOf(limit));
+            {   sql.append("\r\nLIMIT ");
+                sql.append(String.valueOf(limit));
                 // Offset
                 if (skip>=0) 
-                {   buf.append(" OFFSET ");
-                    buf.append(String.valueOf(skip));
+                {   sql.append(" OFFSET ");
+                    sql.append(String.valueOf(skip));
                 }    
             }
         }
@@ -113,13 +114,13 @@ public class DBMSHandlerMySQL extends DBMSHandlerBase
          * @return the delete SQL-Command
          */
         @Override
-        protected void addDeleteWithJoins(StringBuilder buf, DBRowSet table)
+        protected void addDeleteWithJoins(DBSQLBuilder sql, DBRowSet table)
         {
             // DELETE with Multiple-Table Syntax
             // http://dev.mysql.com/doc/refman/5.7/en/delete.html
-            buf.append(table.getAlias());
-            addFrom(buf);
-            addWhere(buf);
+            sql.append(table.getAlias());
+            addFrom(sql);
+            addWhere(sql);
         }
     }
     
@@ -937,17 +938,17 @@ public class DBMSHandlerMySQL extends DBMSHandlerBase
                 skip  = -1;
             }
             @Override
-            public void getSelect(StringBuilder buf)
+            public void getSelect(DBSQLBuilder sql)
             {   // Prepares statement
-            	super.getSelect(buf);
+            	super.getSelect(sql);
                 // add limit and offset
                 if (limit>=0)
-                {   buf.append("\r\nLIMIT ");
-                    buf.append(String.valueOf(limit));
+                {   sql.append("\r\nLIMIT ");
+                    sql.append(String.valueOf(limit));
                     // Offset
                     if (skip>=0) 
-                    {   buf.append(" OFFSET ");
-                        buf.append(String.valueOf(skip));
+                    {   sql.append(" OFFSET ");
+                        sql.append(String.valueOf(skip));
                     }    
                 }
             }
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/mysql/MySQLDDLGenerator.java b/empire-db/src/main/java/org/apache/empire/dbms/mysql/MySQLDDLGenerator.java
index 65b23d72..e3c90c98 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/mysql/MySQLDDLGenerator.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/mysql/MySQLDDLGenerator.java
@@ -29,6 +29,7 @@ import org.apache.empire.db.DBDDLGenerator;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBIndex;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
@@ -65,7 +66,7 @@ public class MySQLDDLGenerator extends DBDDLGenerator<DBMSHandlerMySQL>
     }
 
     @Override
-    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, StringBuilder sql)
+    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, DBSQLBuilder sql)
     {
         switch (type)
         {
@@ -140,7 +141,7 @@ public class MySQLDDLGenerator extends DBDDLGenerator<DBMSHandlerMySQL>
     @Override
     protected void createTable(DBTable t, DBSQLScript script)
     {
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append("-- creating table ");
         sql.append(t.getName());
         sql.append(" --\r\n");
@@ -216,7 +217,7 @@ public class MySQLDDLGenerator extends DBDDLGenerator<DBMSHandlerMySQL>
         cmd.clearOrderBy();
 
         // Build String
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append( "CREATE VIEW ");
         v.addSQL(sql, DBExpr.CTX_FULLNAME);
         sql.append( " (" );
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBCommandOracle.java b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBCommandOracle.java
index 76885fdf..a550c29b 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBCommandOracle.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBCommandOracle.java
@@ -28,6 +28,7 @@ import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBIndex;
 import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.exceptions.NoPrimaryKeyException;
 import org.apache.empire.db.expr.column.DBAliasExpr;
 import org.apache.empire.db.expr.column.DBValueExpr;
@@ -150,10 +151,10 @@ public class DBCommandOracle extends DBCommand
      * Creates an Oracle specific select statement
      * that supports special features of the Oracle DBMS
      * like e.g. CONNECT BY PRIOR
-     * @param buf the SQL statement
+     * @param sql the SQL statement
      */
     @Override
-    public synchronized void getSelect(StringBuilder buf)
+    public synchronized void getSelect(DBSQLBuilder sql)
     {        
         resetParamUsage();
         if (select == null)
@@ -162,57 +163,57 @@ public class DBCommandOracle extends DBCommand
         boolean usePreparedStatements = isPreparedStatementsEnabled();
         if (limitRows>=0)
         {   // add limitRows and skipRows wrapper
-            buf.append("SELECT * FROM (");
+            sql.append("SELECT * FROM (");
             if (skipRows>0)
-                buf.append("SELECT row_.*, rownum rownum_ FROM (");
+                sql.append("SELECT row_.*, rownum rownum_ FROM (");
         }
         // Prepares statement
-        buf.append("SELECT ");
+        sql.append("SELECT ");
         if (StringUtils.isNotEmpty(optimizerHint))
         {   // Append an optimizer hint to the select statement e.g. SELECT /*+ RULE */
-            buf.append("/*+ ").append(optimizerHint).append(" */ ");
+            sql.append("/*+ ").append(optimizerHint).append(" */ ");
         }
         if (selectDistinct)
-            buf.append("DISTINCT ");
+            sql.append("DISTINCT ");
         // Add Select Expressions
-        addListExpr(buf, select, CTX_ALL, ", ");
+        addListExpr(sql, select, CTX_ALL, ", ");
         // Join
-        addFrom(buf);
+        addFrom(sql);
         // Where
-        addWhere(buf);
+        addWhere(sql);
         // Connect By
         if (connectBy != null)
         {   // Add 'Connect By Prior' Expression
-        	buf.append("\r\nCONNECT BY PRIOR ");
-            connectBy.addSQL(buf, CTX_DEFAULT | CTX_NOPARENTHESES);
+        	sql.append("\r\nCONNECT BY PRIOR ");
+            connectBy.addSQL(sql, CTX_DEFAULT | CTX_NOPARENTHESES);
             // Start With
             if (startWith != null)
             {	// Add 'Start With' Expression
-            	buf.append("\r\nSTART WITH ");
-                startWith.addSQL(buf, CTX_DEFAULT);
+            	sql.append("\r\nSTART WITH ");
+                startWith.addSQL(sql, CTX_DEFAULT);
             }
         }
         // Grouping
-        addGrouping(buf);
+        addGrouping(sql);
         // Order
         if (orderBy != null)
         { // Having
             if (connectBy != null)
-                buf.append("\r\nORDER SIBLINGS BY ");
+                sql.append("\r\nORDER SIBLINGS BY ");
             else
-                buf.append("\r\nORDER BY ");
+                sql.append("\r\nORDER BY ");
             // Add List of Order By Expressions
-            addListExpr(buf, orderBy, CTX_DEFAULT, ", ");
+            addListExpr(sql, orderBy, CTX_DEFAULT, ", ");
         }
         // limit rows end
         if (limitRows>=0)
         {   // add limitRows and skipRows constraints
-            buf.append(") row_ WHERE rownum<=");
-            buf.append(usePreparedStatements ? "?" : String.valueOf(skipRows+limitRows));
+            sql.append(") row_ WHERE rownum<=");
+            sql.append(usePreparedStatements ? "?" : String.valueOf(skipRows+limitRows));
             if (skipRows>0)
             {   // add skip rows
-                buf.append(") WHERE rownum_>");
-                buf.append(usePreparedStatements ? "?" : String.valueOf(skipRows));
+                sql.append(") WHERE rownum_>");
+                sql.append(usePreparedStatements ? "?" : String.valueOf(skipRows));
             }
         }
         completeParamUsage();
@@ -239,41 +240,41 @@ public class DBCommandOracle extends DBCommand
     }
 
     @Override
-    protected void addUpdateForTable(StringBuilder buf, DBRowSet table)
+    protected void addUpdateForTable(DBSQLBuilder sql, DBRowSet table)
     {
         // Optimizer Hint
         long context = CTX_FULLNAME;
         if (StringUtils.isNotEmpty(optimizerHint))
         {   // Append an optimizer hint to the select statement e.g. SELECT /*+ RULE */
-            buf.append("/*+ ").append(optimizerHint).append(" */ ");
+            sql.append("/*+ ").append(optimizerHint).append(" */ ");
             // Append alias (if necessary)
             if (optimizerHint.contains(table.getAlias()))
                 context |= CTX_ALIAS;
         }
         // table
-        table.addSQL(buf, context);
+        table.addSQL(sql, context);
         // Simple Statement
         context = CTX_NAME | CTX_VALUE;
         // Set Expressions
-        buf.append("\r\nSET ");
-        addListExpr(buf, set, context, ", ");
+        sql.append("\r\nSET ");
+        addListExpr(sql, set, context, ", ");
         // Add Where
-        addWhere(buf, context);
+        addWhere(sql, context);
     }
     
     @Override
-    protected void addUpdateWithJoins(StringBuilder buf, DBRowSet table)
+    protected void addUpdateWithJoins(DBSQLBuilder sql, DBRowSet table)
     {
         // The update table
         DBColumn[] keyColumns = table.getKeyColumns();
         if (keyColumns==null || keyColumns.length==0)
             throw new NoPrimaryKeyException(table);
         // Generate Merge expression
-        buf.setLength(0);
-        buf.append("MERGE INTO ");
-        table.addSQL(buf, CTX_FULLNAME|CTX_ALIAS);
+        sql.reset(0);
+        sql.append("MERGE INTO ");
+        table.addSQL(sql, CTX_FULLNAME|CTX_ALIAS);
         // Using
-        buf.append("\r\nUSING (");
+        sql.append("\r\nUSING (");
         // Add set expressions
         List<DBColumnExpr> using = new ArrayList<DBColumnExpr>();
         // Add key columns
@@ -304,29 +305,29 @@ public class DBCommandOracle extends DBCommand
             }
         }
         // Add select
-        buf.append("SELECT ");
-        addListExpr(buf, using, CTX_ALL, ", ");
+        sql.append("SELECT ");
+        addListExpr(sql, using, CTX_ALL, ", ");
         // From clause
-        addFrom(buf);
+        addFrom(sql);
         // Add Where
-        addWhere(buf);
+        addWhere(sql);
         // Add Grouping
-        addGrouping(buf);
+        addGrouping(sql);
         // on
-        buf.append(") q0\r\nON (");
+        sql.append(") q0\r\nON (");
         for (DBColumn col : keyColumns)
         {   // compare 
-            buf.append(" q0.");
-            col.addSQL(buf, CTX_NAME);
-            buf.append("=");
-            buf.append(table.getAlias());
-            buf.append(".");
-            col.addSQL(buf, CTX_NAME);
+            sql.append(" q0.");
+            col.addSQL(sql, CTX_NAME);
+            sql.append("=");
+            sql.append(table.getAlias());
+            sql.append(".");
+            col.addSQL(sql, CTX_NAME);
         }
         // Set Expressions
-        buf.append(")\r\nWHEN MATCHED THEN UPDATE ");
-        buf.append("\r\nSET ");
-        addListExpr(buf, mergeSet, CTX_DEFAULT, ", ");
+        sql.append(")\r\nWHEN MATCHED THEN UPDATE ");
+        sql.append("\r\nSET ");
+        addListExpr(sql, mergeSet, CTX_DEFAULT, ", ");
     }
     
     /**
@@ -335,23 +336,23 @@ public class DBCommandOracle extends DBCommand
      */
     
     @Override
-    protected void addDeleteForTable(StringBuilder buf, DBRowSet table)
+    protected void addDeleteForTable(DBSQLBuilder sql, DBRowSet table)
     {
         if (StringUtils.isNotEmpty(optimizerHint))
         {   // Append an optimizer hint to the select statement e.g. SELECT /*+ RULE */
-            buf.append("/*+ ").append(optimizerHint).append(" */ ");
+            sql.append("/*+ ").append(optimizerHint).append(" */ ");
         }
-        super.addDeleteForTable(buf, table);
+        super.addDeleteForTable(sql, table);
     }
     
     @Override
-    protected void addDeleteWithJoins(StringBuilder buf, DBRowSet table)
+    protected void addDeleteWithJoins(DBSQLBuilder sql, DBRowSet table)
     {
         if (StringUtils.isNotEmpty(optimizerHint))
         {   // Append an optimizer hint to the select statement e.g. SELECT /*+ RULE */
-            buf.append("/*+ ").append(optimizerHint).append(" */ ");
+            sql.append("/*+ ").append(optimizerHint).append(" */ ");
         }
-        super.addDeleteWithJoins(buf, table);
+        super.addDeleteWithJoins(sql, table);
     }
 
 }
\ No newline at end of file
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java
index b53f7c44..36d40fb7 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java
@@ -37,6 +37,7 @@ import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBObject;
 import org.apache.empire.db.DBReader;
 import org.apache.empire.db.DBRelation;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
@@ -224,7 +225,7 @@ public class DBMSHandlerOracle extends DBMSHandlerBase
             case SQL_FUNC_MAX:                  return "max(?)";
             case SQL_FUNC_MIN:                  return "min(?)";
             case SQL_FUNC_AVG:                  return "avg(?)";
-            case SQL_FUNC_STRAGG:               return "listagg(? {0}) WITHIN GROUP (ORDER BY {1})";
+            case SQL_FUNC_STRAGG:               return "listagg(?,{0}) WITHIN GROUP (ORDER BY {1})";
             // Others
             case SQL_FUNC_DECODE:               return "decode(? {0})";
             case SQL_FUNC_DECODE_SEP:           return ",";
@@ -344,7 +345,7 @@ public class DBMSHandlerOracle extends DBMSHandlerBase
     @Override
     public Object getNextSequenceValue(DBDatabase db, String seqName, int minValue, Connection conn)
     { // Use Oracle Sequences
-        StringBuilder sql = new StringBuilder(80);
+        DBSQLBuilder sql = new DBSQLBuilder(this);
         sql.append("SELECT ");
         db.appendQualifiedName(sql, seqName, null);
         sql.append(".NEXTVAL FROM DUAL");
@@ -371,7 +372,7 @@ public class DBMSHandlerOracle extends DBMSHandlerBase
         String seqName = StringUtils.toString(column.getDefaultValue());
         if (StringUtils.isEmpty(seqName))
             throw new InvalidArgumentException("column", column);
-        StringBuilder sql = new StringBuilder(80);
+        DBSQLBuilder sql = new DBSQLBuilder(this);
         column.getDatabase().appendQualifiedName(sql, seqName, null);
         sql.append(".NEXTVAL");
         return new DBValueExpr(column.getDatabase(), sql.toString(), DataType.UNKNOWN);
@@ -429,14 +430,14 @@ public class DBMSHandlerOracle extends DBMSHandlerBase
     public void appendEnableRelationStmt(DBRelation r, boolean enable, DBSQLScript script)
     {
         // ALTER TABLE {table.name} {ENABLE|DISABLE} CONSTRAINT {relation.name}
-        StringBuilder b = new StringBuilder();
-        b.append("ALTER TABLE ");
-        r.getForeignKeyTable().addSQL(b, DBExpr.CTX_FULLNAME);
-        b.append(enable ? " ENABLE " : " DISABLE ");
-        b.append("CONSTRAINT ");
-        b.append(r.getName());
+        DBSQLBuilder sql = new DBSQLBuilder(this);
+        sql.append("ALTER TABLE ");
+        r.getForeignKeyTable().addSQL(sql, DBExpr.CTX_FULLNAME);
+        sql.append(enable ? " ENABLE " : " DISABLE ");
+        sql.append("CONSTRAINT ");
+        sql.append(r.getName());
         // add
-        script.addStmt(b);
+        script.addStmt(sql);
     }
     
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleDDLGenerator.java b/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleDDLGenerator.java
index dd85bb62..7eebd618 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleDDLGenerator.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleDDLGenerator.java
@@ -24,6 +24,7 @@ import org.apache.empire.db.DBDDLGenerator;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBObject;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
@@ -59,7 +60,7 @@ public class OracleDDLGenerator extends DBDDLGenerator<DBMSHandlerOracle>
     }
 
     @Override
-    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, StringBuilder sql)
+    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, DBSQLBuilder sql)
     {
         switch (type)
         {
@@ -140,7 +141,7 @@ public class OracleDDLGenerator extends DBDDLGenerator<DBMSHandlerOracle>
     {
         String seqName = dbms.getColumnSequenceName(column);
         // createSQL
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append("-- creating sequence for column ");
         sql.append(column.getFullName());
         sql.append(" --\r\n");
@@ -170,7 +171,7 @@ public class OracleDDLGenerator extends DBDDLGenerator<DBMSHandlerOracle>
     {
         if (comment==null || comment.length()==0)
             return; // Nothing to do
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append("COMMENT ON ");
         sql.append(type);
         sql.append(" ");
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleRowNumExpr.java b/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleRowNumExpr.java
index 7fae8bc9..dad8378a 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleRowNumExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleRowNumExpr.java
@@ -25,6 +25,7 @@ import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.xml.XMLUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -136,17 +137,17 @@ public class OracleRowNumExpr extends DBColumnExpr
     /**
      * Creates the SQL-Command.
      * 
-     * @param buf the SQL-Command
+     * @param sql the SQL-Command
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
     	if (!(db.getDbms() instanceof DBMSHandlerOracle))
     	{
     		log.warn("Oracle RowNumExpression can be used with Oracle databases only!");
     	}
-        buf.append("rownum");
+        sql.append("rownum");
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBCommandPostgres.java b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBCommandPostgres.java
index a900d899..9df31f65 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBCommandPostgres.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBCommandPostgres.java
@@ -23,6 +23,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.exceptions.NoPrimaryKeyException;
 import org.apache.empire.db.expr.compare.DBCompareExpr;
 
@@ -135,53 +136,53 @@ public class DBCommandPostgres extends DBCommand
     }
     
     @Override
-    public void getSelect(StringBuilder buf)
+    public void getSelect(DBSQLBuilder sql)
     {   // call base class
-        super.getSelect(buf);
+        super.getSelect(sql);
         // add limit and offset
         if (limit>=0)
-        {   buf.append("\r\nLIMIT ");
-            buf.append(String.valueOf(limit));
+        {   sql.append("\r\nLIMIT ");
+            sql.append(String.valueOf(limit));
             // Offset
             if (skip>=0) 
-            {   buf.append(" OFFSET ");
-                buf.append(String.valueOf(skip));
+            {   sql.append(" OFFSET ");
+                sql.append(String.valueOf(skip));
             }    
         }
     }
     
     @Override
-    protected void addUpdateWithJoins(StringBuilder buf, DBRowSet table)
+    protected void addUpdateWithJoins(DBSQLBuilder sql, DBRowSet table)
     {
         DBColumn[] keyColumns = table.getKeyColumns();
         if (keyColumns==null || keyColumns.length==0)
             throw new NoPrimaryKeyException(table);
         // Join Update
-        table.addSQL(buf, CTX_NAME);
-        buf.append(" t0");
+        table.addSQL(sql, CTX_NAME);
+        sql.append(" t0");
         long context = CTX_DEFAULT;
         // Set Expressions
-        buf.append("\r\nSET ");
-        addListExpr(buf, set, context, ", ");
+        sql.append("\r\nSET ");
+        addListExpr(sql, set, context, ", ");
         // From clause
-        addFrom(buf);
+        addFrom(sql);
         // Add Where
-        buf.append("\r\nWHERE");
+        sql.append("\r\nWHERE");
         // key columns
         for (DBColumn col : keyColumns)
         {   // compare 
-            buf.append(" t0.");
-            col.addSQL(buf, CTX_NAME);
-            buf.append("=");
-            buf.append(table.getAlias());
-            buf.append(".");
-            col.addSQL(buf, CTX_NAME);
+            sql.append(" t0.");
+            col.addSQL(sql, CTX_NAME);
+            sql.append("=");
+            sql.append(table.getAlias());
+            sql.append(".");
+            col.addSQL(sql, CTX_NAME);
         }
         // more constraints
         if (where!=null && !where.isEmpty())
         {   // add where expression
-            buf.append("\r\n  AND ");
-            addListExpr(buf, where, context, " AND ");
+            sql.append("\r\n  AND ");
+            addListExpr(sql, where, context, " AND ");
         }
     }
 }
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
index 3df62b33..a3644edb 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
@@ -33,6 +33,7 @@ import org.apache.empire.db.DBDDLGenerator;
 import org.apache.empire.db.DBDDLGenerator.DDLActionType;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBObject;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
@@ -289,7 +290,7 @@ public class DBMSHandlerPostgreSQL extends DBMSHandlerBase
         {
             throw new InvalidArgumentException("column", column);
         }
-        StringBuilder sql = new StringBuilder(80);
+        DBSQLBuilder sql = new DBSQLBuilder(this);
         sql.append("nextval('");
         column.getDatabase().appendQualifiedName(sql, seqName, false);
         sql.append("')");
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresAtAt.java b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresAtAt.java
index 0492d195..a4bd4fe7 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresAtAt.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresAtAt.java
@@ -25,6 +25,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.expr.compare.DBCompareExpr;
 
 /**
@@ -86,11 +87,11 @@ public class PostgresAtAt extends DBCompareExpr
     }
 
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
-        this.left.addSQL(buf, context);
-        buf.append(" @@ ");
-        this.right.addSQL(buf, context);
+        this.left.addSQL(sql, context);
+        sql.append(" @@ ");
+        this.right.addSQL(sql, context);
     }
 
     @Override
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresBoolAndOrExpr.java b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresBoolAndOrExpr.java
index 6b790331..c1c51e10 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresBoolAndOrExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresBoolAndOrExpr.java
@@ -25,6 +25,7 @@ import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.expr.compare.DBCompareAndOrExpr;
 import org.apache.empire.db.expr.compare.DBCompareColExpr;
 import org.apache.empire.db.expr.compare.DBCompareExpr;
@@ -105,13 +106,13 @@ public class PostgresBoolAndOrExpr extends DBColumnExpr
     }
 
     @Override
-    public void addSQL(StringBuilder buf, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
 
-        buf.append(or ? BOOL_OR : BOOL_AND);
-        buf.append("(");
-        cmpExpr.addSQL(buf, context);
-        buf.append(")");
+        sql.append(or ? BOOL_OR : BOOL_AND);
+        sql.append("(");
+        cmpExpr.addSQL(sql, context);
+        sql.append(")");
     }
 
     @Override
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresDDLGenerator.java b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresDDLGenerator.java
index 598a81aa..4ed5d16e 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresDDLGenerator.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresDDLGenerator.java
@@ -23,6 +23,7 @@ import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBDDLGenerator;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
@@ -87,7 +88,7 @@ public class PostgresDDLGenerator extends DBDDLGenerator<DBMSHandlerPostgreSQL>
     }
 
     @Override
-    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, StringBuilder sql)
+    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, DBSQLBuilder sql)
     {
         switch (type)
         {
@@ -152,7 +153,7 @@ public class PostgresDDLGenerator extends DBDDLGenerator<DBMSHandlerPostgreSQL>
     {
     	String seqName = dbms.getColumnSequenceName(column);
         // createSQL
-        StringBuilder sql = new StringBuilder();
+        DBSQLBuilder sql = new DBSQLBuilder(dbms);
         sql.append("-- creating sequence for column ");
         sql.append(column.getFullName());
         sql.append(" --\r\n");
@@ -164,7 +165,7 @@ public class PostgresDDLGenerator extends DBDDLGenerator<DBMSHandlerPostgreSQL>
     }
 
     @Override
-    protected void appendColumnDesc(DBTableColumn c, boolean alter, StringBuilder sql)
+    protected void appendColumnDesc(DBTableColumn c, boolean alter, DBSQLBuilder sql)
     {
         // Append name
         c.addSQL(sql, DBExpr.CTX_NAME);
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresFuncExpr.java b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresFuncExpr.java
index 75222475..e6946819 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresFuncExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/PostgresFuncExpr.java
@@ -24,6 +24,7 @@ import org.apache.empire.data.DataType;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.expr.column.DBAbstractFuncExpr;
 
 public class PostgresFuncExpr extends DBAbstractFuncExpr
@@ -77,7 +78,7 @@ public class PostgresFuncExpr extends DBAbstractFuncExpr
      * @param context the current SQL-Command context
      */
     @Override
-    public void addSQL(StringBuilder sql, long context)
+    public void addSQL(DBSQLBuilder sql, long context)
     {
         // Add SQL
         super.addSQL(sql, phrase.getSQL(), params, context);
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/sqlite/SQLiteDDLGenerator.java b/empire-db/src/main/java/org/apache/empire/dbms/sqlite/SQLiteDDLGenerator.java
index 2128fa66..2a8208fd 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/sqlite/SQLiteDDLGenerator.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/sqlite/SQLiteDDLGenerator.java
@@ -28,6 +28,7 @@ import org.apache.empire.db.DBDDLGenerator;
 import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBIndex;
 import org.apache.empire.db.DBRelation;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
@@ -55,7 +56,7 @@ public class SQLiteDDLGenerator extends DBDDLGenerator<DBMSHandlerSQLite>
 	@Override
 	protected void createTable(DBTable t, DBSQLScript script)
 	{
-		StringBuilder sql = new StringBuilder();
+		DBSQLBuilder sql = new DBSQLBuilder(dbms);
 		sql.append("-- creating table ");
 		sql.append(t.getName());
 		sql.append(" --\r\n");
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java b/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
index a7330981..1527f04f 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
@@ -34,6 +34,7 @@ import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBObject;
 import org.apache.empire.db.DBRelation;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTable;
 import org.apache.empire.db.DBTableColumn;
@@ -84,21 +85,21 @@ public class DBMSHandlerMSSQL extends DBMSHandlerBase
         }
         
         @Override
-        protected void addSelect(StringBuilder buf)
+        protected void addSelect(DBSQLBuilder sql)
         {   
             // Prepares statement
-            buf.append("SELECT ");
+            sql.append("SELECT ");
             if (selectDistinct)
-                buf.append("DISTINCT ");
+                sql.append("DISTINCT ");
             // Add limit
             if (limit>=0)
             {   // Limit
-                buf.append("TOP ");
-                buf.append(String.valueOf(limit));
-                buf.append(" ");
+                sql.append("TOP ");
+                sql.append(String.valueOf(limit));
+                sql.append(" ");
             }
             // Add Select Expressions
-            addListExpr(buf, select, CTX_ALL, ", ");
+            addListExpr(sql, select, CTX_ALL, ", ");
         }
     }
     
@@ -458,13 +459,18 @@ public class DBMSHandlerMSSQL extends DBMSHandlerBase
     @Override
     protected String getSQLTextString(DataType type, Object value)
     {
-        StringBuilder valBuf = new StringBuilder();
+        if (value==null)
+            return getSQLPhrase(DBSqlPhrase.SQL_NULL);
+        // text
+        String text = value.toString();
+        StringBuilder valBuf = new StringBuilder(text.length()+4);
         // for SQLSERVER utf8 support, see EMPIREDB-122
         valBuf.append((useUnicodePrefix) ? "N'" : "'");
         if (DBDatabase.EMPTY_STRING.equals(value)==false)
-            appendSQLTextValue(valBuf, value.toString());
+            appendSQLTextValue(valBuf, text);
         valBuf.append("'");
         return valBuf.toString();
+        
     }
     
     /**
@@ -553,14 +559,14 @@ public class DBMSHandlerMSSQL extends DBMSHandlerBase
     public void appendEnableRelationStmt(DBRelation r, boolean enable, DBSQLScript script)
     {
         // ALTER TABLE {table.name} {CHECK|NOCHECK} CONSTRAINT {relation.name}
-        StringBuilder b = new StringBuilder();
-        b.append("ALTER TABLE ");
-        r.getForeignKeyTable().addSQL(b, DBExpr.CTX_FULLNAME);
-        b.append(enable ? " CHECK " : " NOCHECK ");
-        b.append("CONSTRAINT ");
-        b.append(r.getName());
+        DBSQLBuilder sql = new DBSQLBuilder(this);
+        sql.append("ALTER TABLE ");
+        r.getForeignKeyTable().addSQL(sql, DBExpr.CTX_FULLNAME);
+        sql.append(enable ? " CHECK " : " NOCHECK ");
+        sql.append("CONSTRAINT ");
+        sql.append(r.getName());
         // add
-        script.addStmt(b);
+        script.addStmt(sql);
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/MSSqlDDLGenerator.java b/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/MSSqlDDLGenerator.java
index 172bf0ea..f538cbf7 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/MSSqlDDLGenerator.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/MSSqlDDLGenerator.java
@@ -28,9 +28,10 @@ import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBIndex;
 import org.apache.empire.db.DBIndex.DBIndexType;
-import org.apache.empire.dbms.DBMSHandlerBase.DBSeqTable;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.DBTableColumn;
+import org.apache.empire.dbms.DBMSHandlerBase.DBSeqTable;
 
 public class MSSqlDDLGenerator extends DBDDLGenerator<DBMSHandlerMSSQL>
 {
@@ -59,7 +60,7 @@ public class MSSqlDDLGenerator extends DBDDLGenerator<DBMSHandlerMSSQL>
     }
 
     @Override
-    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, StringBuilder sql)
+    protected boolean appendColumnDataType(DataType type, double size, DBTableColumn c, DBSQLBuilder sql)
     {
         switch (type)
         {
@@ -129,7 +130,7 @@ public class MSSqlDDLGenerator extends DBDDLGenerator<DBMSHandlerMSSQL>
     }
     
     @Override
-    protected void addCreateIndexStmt(DBIndex index, StringBuilder sql, DBSQLScript script)
+    protected void addCreateIndexStmt(DBIndex index, DBSQLBuilder sql, DBSQLScript script)
     {
         // Check type
         if (index.getType()==DBIndexType.UNIQUE_ALLOW_NULL)
diff --git a/empire-db/src/test/java/org/apache/empire/db/expr/set/DBSetExprTest.java b/empire-db/src/test/java/org/apache/empire/db/expr/set/DBSetExprTest.java
index 760449dc..9992c77f 100644
--- a/empire-db/src/test/java/org/apache/empire/db/expr/set/DBSetExprTest.java
+++ b/empire-db/src/test/java/org/apache/empire/db/expr/set/DBSetExprTest.java
@@ -28,21 +28,24 @@ import org.apache.empire.db.CompanyDB;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBExpr;
+import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.MockDriver;
 import org.apache.empire.db.context.DBContextStatic;
+import org.apache.empire.dbms.DBMSHandler;
 import org.junit.Before;
 import org.junit.Test;
 
 public class DBSetExprTest
 {
-    
+    private DBMSHandler dbms;
     private DBSetExpr expr;
     private CompanyDB testDB;
     
     @Before
     public void setup(){
+        dbms = new MockDriver();
         testDB = new CompanyDB();
-        testDB.open(new DBContextStatic(new MockDriver(), null));
+        testDB.open(new DBContextStatic(dbms, null));
         expr = new DBSetExpr(testDB.EMPLOYEE.FIRSTNAME, "JUnit");
     }
 
@@ -55,7 +58,7 @@ public class DBSetExprTest
     @Test
     public void testAddSQL()
     {
-        StringBuilder builder = new StringBuilder();
+        DBSQLBuilder builder = new DBSQLBuilder(dbms);
         expr.addSQL(builder, 0);
         assertEquals("", builder.toString());
         expr.addSQL(builder, DBExpr.CTX_DEFAULT);
@@ -65,7 +68,7 @@ public class DBSetExprTest
     @Test
     public void testAddSQLEmptyString()
     {
-        StringBuilder builder = new StringBuilder();
+        DBSQLBuilder builder = new DBSQLBuilder(dbms);
         DBSetExpr setExpr = new DBSetExpr(testDB.EMPLOYEE.FIRSTNAME, "");
         setExpr.addSQL(builder, DBExpr.CTX_DEFAULT);
         // Empire-DB by default sees '' as null
@@ -75,7 +78,7 @@ public class DBSetExprTest
     @Test
     public void testAddSQLEmptyStringConstant()
     {
-        StringBuilder builder = new StringBuilder();
+        DBSQLBuilder builder = new DBSQLBuilder(dbms);
         DBSetExpr setExpr = new DBSetExpr(testDB.EMPLOYEE.FIRSTNAME, DBDatabase.EMPTY_STRING);
         setExpr.addSQL(builder, DBExpr.CTX_DEFAULT);
         assertEquals("FIRSTNAME=''", builder.toString());