EMPIREDB-394 reworked CmdParam generation
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 e1ffc31..94f0225 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
@@ -102,7 +102,7 @@
     {

         sql.append("?"); //$NON-NLS-1$

         // Move to current usage position

-        cmd.notifyParamUsage(this);

+        cmd.cmdParams.notifyParamUsage(this);

     }

     

     /**

diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCmdParamList.java b/empire-db/src/main/java/org/apache/empire/db/DBCmdParamList.java
new file mode 100644
index 0000000..0deefb1
--- /dev/null
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCmdParamList.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.db;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.empire.data.DataType;
+import org.apache.empire.exceptions.NotSupportedException;
+import org.apache.empire.exceptions.UnspecifiedErrorException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * DBCmdParamList
+ * This class handles command parameters for Prepared Statements
+ */
+public class DBCmdParamList implements DBCmdParams
+{
+    protected static final Logger log = LoggerFactory.getLogger(DBCmdParamList.class);
+
+    protected ArrayList<DBCmdParam> cmdParams;
+    
+    private int paramUsageCount = 0;
+
+    public DBCmdParamList()
+    {
+        cmdParams = null;
+    }
+
+    public DBCmdParamList(int size)
+    {
+        cmdParams = (size>0 ? new ArrayList<>(size) : null);
+    }
+    
+    @Override
+    public boolean isEmpty()
+    {
+        return (cmdParams==null || cmdParams.isEmpty());
+    }
+    
+    @Override
+    public int size()
+    {
+        return (cmdParams==null ? 0 : cmdParams.size());
+    }
+
+    @Override
+    public Iterator<DBCmdParam> iterator()
+    {
+        if (cmdParams==null)
+            throw new NotSupportedException(this, "iterator");
+        return cmdParams.iterator();
+    }
+    
+    public void clear(int capacity)
+    {
+        paramUsageCount = 0;
+        if (capacity>0)
+            cmdParams= new ArrayList<DBCmdParam>(capacity);
+        else
+            cmdParams = null;
+    }
+    
+    public void add(DBCmdParam param)
+    {
+        if (cmdParams==null)
+            cmdParams= new ArrayList<DBCmdParam>();
+        // Create and add the parameter to the parameter list 
+        cmdParams.add(param);
+    }
+    
+    public void remove(DBCmdParam param)
+    {
+        if (cmdParams==null || !cmdParams.remove(param))
+            log.warn("Unable to remove DBCmdParam: Param not found");
+    }
+    
+    public Object[] getParamValues()
+    {
+        if (cmdParams==null || paramUsageCount==0)
+            return null;
+        // Check whether all parameters have been used
+        if (paramUsageCount!=cmdParams.size())
+            log.info("DBCommand parameter count ("+String.valueOf(cmdParams.size())
+                   + ") does not match parameter use count ("+String.valueOf(paramUsageCount)+")");
+        // Create result array
+        Object[] values = new Object[paramUsageCount];
+        for (int i=0; i<values.length; i++)
+            values[i]=cmdParams.get(i).getValue();
+        // values
+        return values;
+    }
+    
+    /**
+     * internally used to reset the command param usage count.
+     * Note: Only one thread my generate an SQL statement 
+     */
+    public void resetParamUsage(DBCommand cmd)
+    {
+        paramUsageCount = 0;
+        if (cmdParams==null)
+            return;
+        // clear subquery params
+        for (int i=cmdParams.size()-1; i>=0 ;i--)
+            if (cmdParams.get(i).getCmd()!=cmd)
+                cmdParams.remove(i);
+    }
+    
+    /**
+     * internally used to remove unused Command Params from list
+     * Note: Only one thread my generate an SQL statement 
+     */
+    public void completeParamUsage(DBCommand cmd)
+    {
+        if (cmdParams==null)
+            return;
+        // check whether all params have been used
+        if (paramUsageCount < cmdParams.size())
+        {   // Remove unused parameters
+            log.warn("DBCommand has {} unused Command params", cmdParams.size()-paramUsageCount);
+            for (int i=cmdParams.size()-1; i>=paramUsageCount; i--)
+            {   // Remove temporary params
+                if (cmdParams.get(i).getCmd()!=cmd)
+                    cmdParams.remove(i);
+            }
+        }
+    }
+    
+    /**
+     * internally used to reorder the command params to match their order of occurance
+     */
+    protected void notifyParamUsage(DBCmdParam param)
+    {
+        int index = cmdParams.indexOf(param);
+        if (index<0) 
+        {   // Error: parameter probably used twice in statement!
+            throw new UnspecifiedErrorException("The CmdParam has not been found on this Command.");
+        }
+        if (index < paramUsageCount)
+        {   // Warn: parameter used twice in statement!
+            log.debug("The DBCmdParam already been used. Adding a temporary copy");
+            cmdParams.add(paramUsageCount, new DBCmdParam(null, param.getDataType(), param.getValue()));
+        }
+        else if (index > paramUsageCount)
+        {   // Correct parameter order
+            cmdParams.remove(index);
+            cmdParams.add(paramUsageCount, param);
+        }
+        paramUsageCount++;
+    }
+    
+    public void mergeSubqueryParams(DBCmdParams subQueryParams)
+    {
+        if (subQueryParams==null || subQueryParams.isEmpty())
+            return;
+        // Subquery has parameters
+        if (cmdParams==null)
+            cmdParams= new ArrayList<DBCmdParam>(subQueryParams.size());
+        for (DBCmdParam p : subQueryParams)
+            cmdParams.add(paramUsageCount++, new DBCmdParam(null, DataType.UNKNOWN, p.getValue()));
+    }
+
+    /*
+    protected void mergeSubqueryParamsObsolete(Object[] subQueryParams)
+    {
+        if (subQueryParams==null || subQueryParams.length==0)
+            return;
+        // Subquery has parameters
+        if (cmdParams==null)
+            cmdParams= new ArrayList<DBCmdParam>(subQueryParams.length);
+        for (int p=0; p<subQueryParams.length; p++)
+            cmdParams.add(paramUsageCount++, new DBCmdParam(null, DataType.UNKNOWN, subQueryParams[p]));
+        log.warn("mergeSubqueryParamsObsolete");
+    }
+    
+    public void addJoin(DBSQLBuilder sql, DBJoinExpr join, long context, int whichParams)
+    {
+        // remember insert pos
+        int paramInsertPos = paramUsageCount;
+        // now add the join
+        join.addSQL(sql, context);
+        // Merge subquery params
+        Object[] subQueryParams = join.getSubqueryParams(whichParams);
+        if (subQueryParams!=null)
+        {
+            if (paramInsertPos == paramUsageCount)
+                mergeSubqueryParamsObsolete(subQueryParams);
+            else
+            {   // Some Params have been used in additional Join constraints
+                int tempCounter = paramUsageCount;
+                paramUsageCount = paramInsertPos;
+                mergeSubqueryParamsObsolete(subQueryParams);
+                int insertCount = (paramUsageCount - paramInsertPos);
+                paramUsageCount = tempCounter + insertCount;
+            }
+        }
+    }
+    */
+    
+}
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCmdParams.java b/empire-db/src/main/java/org/apache/empire/db/DBCmdParams.java
new file mode 100644
index 0000000..9ee2c76
--- /dev/null
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCmdParams.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.db;
+
+/**
+ * DBCmdParams
+ * Provides information about the command parameters used in a DBCommand
+ */
+public interface DBCmdParams extends Iterable<DBCmdParam>
+{
+    boolean isEmpty();
+    
+    int size();
+}
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 738e245..fa1d5c0 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
@@ -19,6 +19,7 @@
 package org.apache.empire.db;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
@@ -128,8 +129,43 @@
         return left.getSelectExprList();
     }
 
+    @Override
+    public DBCmdParams getParams()
+    {
+        DBCmdParams lp = left.getParams();
+        DBCmdParams rp = right.getParams();
+        if (lp.isEmpty())
+            return rp;
+        if (rp.isEmpty())
+            return lp;
+        // combine
+        DBCmdParams params = new DBCmdParams() {
+            final ArrayList<DBCmdParam> list = new ArrayList<DBCmdParam>(lp.size()+rp.size());
+            {
+                for (DBCmdParam p : lp)
+                    list.add(p);
+                for (DBCmdParam p : rp)
+                    list.add(p);
+            }
+            @Override
+            public boolean isEmpty() {
+                return list.isEmpty();
+            }
+            @Override
+            public int size() {
+                return list.size();
+            }
+            @Override
+            public Iterator<DBCmdParam> iterator() {
+                return list.iterator();
+            }
+        };
+        return params;
+    }
+
     /**
     * Returns the list of parameter values for a prepared statement.
+    * To ensure the correct order, getSelect() must be called first.
     * @return the list of parameter values for a prepared statement 
     */
     @Override
@@ -151,7 +187,7 @@
         // return Params
         return allParams;
     }
-
+    
     /**
     * @return the DataType of the selected expression or DataType.UNKNOWN
     */
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 3b28779..147566b 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
@@ -44,7 +44,6 @@
 import org.apache.empire.exceptions.InvalidArgumentException;
 import org.apache.empire.exceptions.ItemNotFoundException;
 import org.apache.empire.exceptions.ObjectNotValidException;
-import org.apache.empire.exceptions.UnspecifiedErrorException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,21 +61,27 @@
     // Logger
     protected static final Logger log             = LoggerFactory.getLogger(DBCommand.class);
 
+    @Override
+    protected DBSQLBuilder createSQLBuilder(String initalSQL)
+    {
+        DBSQLBuilder sql = super.createSQLBuilder(initalSQL);
+        sql.setCmdParams(this.cmdParams);
+        return sql;
+    }
+
     // Distinct Select
-    protected boolean             selectDistinct  = false;
+    protected boolean              selectDistinct  = false;
     // Lists
-    protected List<DBColumnExpr>  select          = null;
-    protected List<DBSetExpr>     set             = null;
-    protected List<DBJoinExpr>    joins           = null;
-    protected List<DBCompareExpr> where           = null;
-    protected List<DBCompareExpr> having          = null;
-    protected List<DBColumnExpr>  groupBy         = null;
+    protected List<DBColumnExpr>   select          = null;
+    protected List<DBSetExpr>      set             = null;
+    protected List<DBJoinExpr>     joins           = null;
+    protected List<DBCompareExpr>  where           = null;
+    protected List<DBCompareExpr>  having          = null;
+    protected List<DBColumnExpr>   groupBy         = null;
 
     // Parameters for prepared Statements generation
-    protected boolean             autoPrepareStmt = false;
-    protected List<DBCmdParam>    cmdParams       = null;
-    private int                   paramUsageCount = 0;
-
+    protected boolean              autoPrepareStmt = false;
+    protected DBCmdParamList       cmdParams;
 
     /**
      * Custom serialization for transient database.
@@ -107,12 +112,23 @@
      * 
      * @param db the current database object
      */
-    protected DBCommand(boolean autoPrepareStmt)
+    protected DBCommand(boolean autoPrepareStmt, DBCmdParamList cmdParams)
     {
         this.autoPrepareStmt = autoPrepareStmt;
+        this.cmdParams = cmdParams;
     }
 
     /**
+     * Constructs a new DBCommand object and set the specified DBDatabase object.
+     * 
+     * @param db the current database object
+     */
+    protected DBCommand(boolean autoPrepareStmt)
+    {
+        this(autoPrepareStmt, new DBCmdParamList());
+    }
+    
+    /**
      * @return true if auto Prepared Statements is activated for this record
      */
     public final boolean isAutoPrepareStmt()
@@ -140,11 +156,10 @@
             clone.groupBy = new ArrayList<DBColumnExpr>(groupBy);
         if (having!=null)
             clone.having = new ArrayList<DBCompareExpr>(having);
-        if (cmdParams!=null && !cmdParams.isEmpty())
-        {   // clone params
-            clone.paramUsageCount = 0;
-            clone.cmdParams = new ArrayList<DBCmdParam>(cmdParams.size());
-            // clone set
+        // clone params
+        clone.cmdParams = new DBCmdParamList(cmdParams.size());
+        if (!cmdParams.isEmpty())
+        {   // clone set
             for (int i=0; (clone.set!=null && i<clone.set.size()); i++)
                 clone.set.set(i, clone.set.get(i).copy(clone));
             // clone joins
@@ -176,6 +191,12 @@
         // not valid yet
         throw new ObjectNotValidException(this);
     }
+
+    @Override
+    public DBCmdParams getParams()
+    {
+        return cmdParams;
+    }
     
     /**
      * internally used to reset the command param usage count.
@@ -183,13 +204,7 @@
      */
     protected void resetParamUsage()
     {
-        paramUsageCount = 0;
-        if (cmdParams==null)
-            return;
-        // clear subquery params
-        for (int i=cmdParams.size()-1; i>=0 ;i--)
-            if (cmdParams.get(i).getCmd()!=this)
-                cmdParams.remove(i);
+        cmdParams.resetParamUsage(this);
     }
     
     /**
@@ -198,56 +213,22 @@
      */
     protected void completeParamUsage()
     {
-        if (cmdParams==null)
-            return;
-        // check whether all params have been used
-        if (paramUsageCount < cmdParams.size())
-        {   // Remove unused parameters
-            log.warn("DBCommand has {} unused Command params", cmdParams.size()-paramUsageCount);
-            for (int i=cmdParams.size()-1; i>=paramUsageCount; i--)
-            {   // Remove temporary params
-                if (cmdParams.get(i).getCmd()!=this)
-                    cmdParams.remove(i);
-            }
-        }
+        cmdParams.completeParamUsage(this);
     }
     
     /**
-     * internally used to reorder the command params to match their order of occurance
-     */
-    protected void notifyParamUsage(DBCmdParam param)
-    {
-        int index = cmdParams.indexOf(param);
-        if (index<0) 
-        {   // Error: parameter probably used twice in statement!
-            throw new UnspecifiedErrorException("The CmdParam has not been found on this Command.");
-        }
-        if (index < paramUsageCount)
-        {   // Warn: parameter used twice in statement!
-            log.debug("The DBCmdParam already been used. Adding a temporary copy");
-            cmdParams.add(paramUsageCount, new DBCmdParam(null, param.getDataType(), param.getValue()));
-        }
-        else if (index > paramUsageCount)
-        {   // Correct parameter order
-            cmdParams.remove(index);
-            cmdParams.add(paramUsageCount, param);
-        }
-        paramUsageCount++;
-    }
-
-    /**
      * internally used to remove the command param used in a constraint
      */
    	protected void removeCommandParams(DBCompareExpr cmpExpr) 
    	{
-   	    if (cmdParams==null)
+   	    if (cmdParams.isEmpty())
    	        return; // Nothing to do
    	    // check type
    	    if (cmpExpr instanceof DBCompareColExpr)
    	    {   // DBCompareColExpr
    	        DBCompareColExpr cmp = ((DBCompareColExpr)cmpExpr);
             if (cmp.getValue() instanceof DBCmdParam)
-                cmdParams.remove(cmp.getValue());
+                cmdParams.remove((DBCmdParam)cmp.getValue());
    	    }
         else if (cmpExpr instanceof DBCompareAndOrExpr) 
         {   // DBCompareAndOrExpr
@@ -269,7 +250,7 @@
      */
    	protected void removeAllCommandParams(List<DBCompareExpr> list)
     {
-        if (cmdParams == null)
+        if (list==null)
         	return;
         for(DBCompareExpr cmp : list)
         {   // Check the value is a DBCommandParam
@@ -545,8 +526,8 @@
                 } 
                 else
                 {   // remove from parameter list (if necessary)
-                    if (cmdParams!=null && (chk.value instanceof DBCmdParam))
-                        cmdParams.remove(chk.value);
+                    if (chk.value instanceof DBCmdParam)
+                        cmdParams.remove((DBCmdParam)chk.value);
                 }
                 // replace now
                 set.set(i, expr);
@@ -621,8 +602,6 @@
      */
     public DBCmdParam addParam(DataType type, Object value)
     {
-        if (cmdParams==null)
-            cmdParams= new ArrayList<DBCmdParam>();
         // Create and add the parameter to the parameter list 
         DBCmdParam param = new DBCmdParam(this, type, value);
         cmdParams.add(param);
@@ -1276,13 +1255,13 @@
      */
     public void clearSet()
     {
-        if (set!=null && cmdParams!=null)
+        if (set!=null && !cmdParams.isEmpty())
         {   // remove params
             for (DBSetExpr set : this.set)
             {   // remove all
                 Object value = set.getValue();
                 if (value instanceof DBCmdParam)
-                    cmdParams.remove(value);
+                    cmdParams.remove((DBCmdParam)value);
             }
         }
         set = null;
@@ -1372,7 +1351,7 @@
      */
     public void clear()
     {
-        cmdParams = null;
+        cmdParams.clear(0);
         clearSelectDistinct();
         clearSelect();
         clearSet();
@@ -1382,7 +1361,7 @@
         clearGroupBy();
         clearOrderBy();
         clearLimit();
-        resetParamUsage();
+        // cmdParams.resetParamUsage(this);
     }
     
     /**
@@ -1575,18 +1554,8 @@
     @Override
     public Object[] getParamValues()
     {
-        if (cmdParams==null || paramUsageCount==0)
-            return null;
-        // Check whether all parameters have been used
-        if (paramUsageCount!=cmdParams.size())
-	        log.info("DBCommand parameter count ("+String.valueOf(cmdParams.size())
-                   + ") does not match parameter use count ("+String.valueOf(paramUsageCount)+")");
-        // Create result array
-        Object[] values = new Object[paramUsageCount];
-        for (int i=0; i<values.length; i++)
-            values[i]=cmdParams.get(i).getValue();
         // values
-        return values;
+        return cmdParams.getParamValues();
     }
     
     /**
@@ -1761,7 +1730,7 @@
         resetParamUsage();
         DBSQLBuilder sql = createSQLBuilder("DELETE ");
         // joins or simple
-         if (joins!=null && !joins.isEmpty())
+        if (joins!=null && !joins.isEmpty())
         {   // delete with joins
             addDeleteWithJoins(sql, table);
         }
@@ -1809,7 +1778,7 @@
         sql.append("\r\nFROM ");
         // Join
         boolean sep = false;
-        int whichParams = 0;
+        // int whichParams = 0;
         List<DBRowSet> tables = getRowSetList();
         if (joins!=null && joins.size()>0)
         {   // Join
@@ -1827,7 +1796,7 @@
                      tables.remove(join.getRightTable());
                      // Context
                      context = CTX_NAME|CTX_VALUE;
-                     whichParams = 0;
+                     // whichParams = 0;
                  }
                  else
                  {   // Extend the join                    
@@ -1839,10 +1808,11 @@
                      // Context
                      context = CTX_VALUE;
                      sql.append( "\t" );
-                     whichParams = 1;
+                     // whichParams = 1;
                  }
                  // check
-                 addJoin(sql, join, context, whichParams);
+                 join.addSQL(sql, context);
+                 // cmdParams.addJoin(sql, join, context, whichParams);
                  // add CRLF
                  if( i!=joins.size()-1 )
                      sql.append("\r\n");
@@ -1854,11 +1824,6 @@
             if (sep) sql.append(", ");
             DBRowSet t = tables.get(i); 
             t.addSQL(sql, CTX_DEFAULT|CTX_ALIAS);
-            // check for query
-            if (t instanceof DBQuery)
-            {   // Merge subquery params
-                mergeSubqueryParams(((DBQuery)t).getCommandExpr().getParamValues());
-            }
             sep = true;
         }
         if (sep==false)
@@ -1874,40 +1839,6 @@
             }
         }
     }
-    
-    protected void addJoin(DBSQLBuilder sql, DBJoinExpr join, long context, int whichParams)
-    {
-        // remember insert pos
-        int paramInsertPos = paramUsageCount;
-        // now add the join
-        join.addSQL(sql, context);
-        // Merge subquery params
-        Object[] subQueryParams = join.getSubqueryParams(whichParams);
-        if (subQueryParams!=null)
-        {
-            if (paramInsertPos == paramUsageCount)
-                mergeSubqueryParams(subQueryParams);
-            else
-            {   // Some Params have been used in additional Join constraints
-                int tempCounter = paramUsageCount;
-                paramUsageCount = paramInsertPos;
-                mergeSubqueryParams(subQueryParams);
-                int insertCount = (paramUsageCount - paramInsertPos);
-                paramUsageCount = tempCounter + insertCount;
-            }
-        }
-    }
-    
-    protected void mergeSubqueryParams(Object[] subQueryParams)
-    {
-        if (subQueryParams==null || subQueryParams.length==0)
-            return;
-        // Subquery has parameters
-        if (cmdParams==null)
-            cmdParams= new ArrayList<DBCmdParam>(subQueryParams.length);
-        for (int p=0; p<subQueryParams.length; p++)
-            cmdParams.add(paramUsageCount++, new DBCmdParam(null, DataType.UNKNOWN, subQueryParams[p]));
-    }
 
     protected void addWhere(DBSQLBuilder sql, long context)
     {
@@ -1923,18 +1854,6 @@
     {
         addWhere(sql, CTX_DEFAULT);
     }
-    
-    @Override
-    protected void addSqlExpr(DBSQLBuilder sql, DBExpr expr, long context)
-    {
-        // append
-        super.addSqlExpr(sql, expr, context);
-        // check for DBCompareExpr
-        if (expr instanceof DBCompareExpr)
-        {   // merge
-            mergeSubqueryParams(((DBCompareExpr)expr).getSubqueryParams());
-        }
-    }
 
     protected void addGrouping(DBSQLBuilder sql)
     {
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 a51c24e..c9f270e 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
@@ -106,7 +106,7 @@
         public void addSQL(DBSQLBuilder sql, long context)
         {
             sql.append("(");
-            sql.append(cmd.getSelect());
+            sql.append(cmd);
             sql.append(")");
         }
 
@@ -353,9 +353,11 @@
         return sql.toString();
     }
     
+    public abstract DBCmdParams getParams();
+
     /**
      * returns an array holding all parameter values in the order of their occurrence.
-     * To ensure the correct order, getSelect() should be called first.
+     * To ensure the correct order, getSelect() must be called first.
      * @return an array of command parameter values 
      */
     public abstract Object[] getParamValues();
@@ -390,7 +392,7 @@
     public void addSQL(DBSQLBuilder sql, long context)
     {
         sql.append("(");
-        sql.append(getSelect());
+        sql.append(this);
         sql.append(")");
     }
 
@@ -606,7 +608,7 @@
      */
     protected DBSQLBuilder createSQLBuilder(String initalSQL)
     {
-        DBSQLBuilder sql = new DBSQLBuilder(getDbms());
+        DBSQLBuilder sql = getDbms().createSQLBuilder();
         if (initalSQL!=null)
             sql.append(initalSQL);
         return sql;
@@ -647,22 +649,11 @@
             if (i > 0)
                 sql.append(separator);
             // append
-            addSqlExpr(sql, list.get(i), context);
+            list.get(i).addSQL(sql, context);
         }
     }
     
     /**
-     * Internally used to append a single DBExpr to a sql command builder
-     * @param sql the sql target buffer
-     * @param expr the expression to append
-     * @param context the sql command context
-     */
-    protected void addSqlExpr(DBSQLBuilder sql, DBExpr expr, long context)
-    {
-        expr.addSQL(sql, context);
-    }
-    
-    /**
      * Create the insert into SQL-Command which copies data
      * from a select statement to a destination table.
      * 
@@ -673,8 +664,7 @@
         if (select == null)
             throw new ObjectNotValidException(this);
         // prepare buffer
-        DBSQLBuilder sql = new DBSQLBuilder(getDatabase().getDbms());
-        sql.append("INSERT INTO ");
+        DBSQLBuilder sql = createSQLBuilder("INSERT INTO ");
         table.addSQL(sql, CTX_FULLNAME);
         // destination columns
         if (columns != null && columns.size() > 0)
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 3cb203e..1c37980 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
@@ -383,7 +383,7 @@
      */

     protected void createTable(DBTable t, DBSQLScript script)

     {

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         sql.append("-- creating table ");

         sql.append(t.getName());

         sql.append(" --\r\n");

@@ -454,7 +454,7 @@
      */

     protected void createIndex(DBTable t, DBIndex idx, DBSQLScript script)

     {

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         // Create Index

         sql.append((idx.getType().isUnique()) ? "CREATE UNIQUE INDEX " : "CREATE INDEX ");

         appendElementName(sql, idx.getName());

@@ -487,7 +487,7 @@
         DBTable sourceTable = (DBTable) r.getReferences()[0].getSourceColumn().getRowSet();

         DBTable targetTable = (DBTable) r.getReferences()[0].getTargetColumn().getRowSet();

 

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         sql.append("-- creating foreign key constraint ");

         sql.append(r.getName());

         sql.append(" --\r\n");

@@ -535,7 +535,7 @@
      */

     protected void alterTable(DBTableColumn col, DDLActionType type, DBSQLScript script)

     {

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         sql.append("ALTER TABLE ");

         col.getRowSet().addSQL(sql, DBExpr.CTX_FULLNAME);

         switch(type)

@@ -580,7 +580,7 @@
         cmd.clearOrderBy();

 

         // Build String

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         sql.append( "CREATE VIEW ");

         v.addSQL(sql, DBExpr.CTX_FULLNAME);

         sql.append( " (" );

@@ -611,7 +611,7 @@
         if (StringUtils.isEmpty(name))

             throw new InvalidArgumentException("name", name);

         // Create Drop Statement

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         sql.append("DROP ");

         sql.append(objType);

         sql.append(" ");

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 aa682a8..78e7d09 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
@@ -335,7 +335,7 @@
     public void addSQL(DBSQLBuilder sql, long context)

     {

         sql.append("(");

-        sql.append(cmdExpr.getSelect());

+        sql.append(cmdExpr);

         sql.append(")");

         // Add Alias

         if ((context & CTX_ALIAS) != 0 && alias != null)

diff --git a/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
index 2fbb3e4..420be5d 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
@@ -31,10 +31,10 @@
 
 /**
  * DBSQLBuilder
- * This class is used when building a single SQL-statement 
+ * This class is used for building a single SQL statement 
  * @author doebele
  */
-public class DBSQLBuilder implements Appendable
+public abstract class DBSQLBuilder implements Appendable
 {
     private static final Logger log = LoggerFactory.getLogger(DBSQLBuilder.class);
     
@@ -42,11 +42,22 @@
     
     private final StringBuilder sql = new StringBuilder(64);
     
-    public DBSQLBuilder(DBMSHandler dbms)
+    private DBCmdParamList cmdParamList;
+
+    /**
+     *  Don't use this directly
+     *  Use dbms.createSQLBuilder()
+     */
+    protected DBSQLBuilder(DBMSHandler dbms)
     {
         this.dbms = dbms;
     }
     
+    public void setCmdParams(DBCmdParamList cmdParamList)
+    {
+        this.cmdParamList = cmdParamList;
+    }
+    
     /*
      * getters
      */
@@ -99,6 +110,27 @@
         sql.append(dbms.getSQLPhrase(phrase));
         return this;
     }
+    
+    public void append(DBCommandExpr subQueryCmd)
+    {
+        // subQueryCmd.addSQL(this, DBExpr.CTX_DEFAULT);
+        sql.append(subQueryCmd.getSelect());
+        
+        DBCmdParams params = subQueryCmd.getParams();
+        if (params.isEmpty())
+            return;
+
+        cmdParamList.mergeSubqueryParams(params);
+        
+        /*
+        // Check CmdParams
+        Object[] paramValues = subQueryCmd.getParamValues();
+        if (paramValues!=null && paramValues.length>0)
+        {   // Params Available
+            cmdParamList.mergeSubqueryParams(paramValues);
+        }
+        */
+    }
 
     @Override
     public DBSQLBuilder append(char c)
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 71d5236..88c048c 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
@@ -18,6 +18,7 @@
  */
 package org.apache.empire.db.expr.column;
 
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -85,10 +86,19 @@
     public String getName()
     {
         DBCompareExpr firstCmpExpr = whenMap.keySet().iterator().next();
-        DBSQLBuilder sql = new DBSQLBuilder(getDatabase().getDbms());
-        sql.append("CASE_");
-        firstCmpExpr.addSQL(sql, CTX_NAME);
-        return sql.toString();
+        Set<DBColumn> cols = new HashSet<DBColumn>(1);
+        firstCmpExpr.addReferencedColumns(cols);
+        // build name
+        StringBuilder name = new StringBuilder(); 
+        name.append("CASE");
+        for (DBColumn col : cols)
+        {
+            name.append("_");
+            // name.append(col.getRowSet().getName());
+            // name.append("_");
+            name.append(col.getName());
+        }
+        return name.toString();
     }
 
     @Override
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 fb657e8..83d2a23 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
@@ -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.DBQuery;
 import org.apache.empire.db.DBRowSet;
 import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.xml.XMLUtil;
@@ -189,6 +190,8 @@
     {
         if (column!=null)
             column.addReferencedColumns(list);
+        else if (rowset instanceof DBQuery)
+            list.add(((DBQuery)rowset).getQueryColumns()[0]);
         else
             list.add(rowset.getColumn(0)); // select any column
     }
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 0a719d2..1f0b9de 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
@@ -164,7 +164,6 @@
     /**
      * Returns the subquery params if the two expressions to be combined
      * @return the subquery params or null
-     */
     @Override
     public Object[] getSubqueryParams()
     {
@@ -172,6 +171,7 @@
         Object[] rParams = right.getSubqueryParams();
         return ObjectUtils.combine(lParams, rParams);
     }
+     */
     
     /**
      * Returns whether the constraint should replace another one or not.
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 ef3ca85..bab0d1b 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
@@ -256,6 +256,8 @@
                 // NONE
                 sql.append(" ");
         }
+        if (value instanceof DBCommandExpr)
+            System.out.println("DBCommandExpr");
         // append value
         sql.appendValue(expr.getDataType(), value, context, arraySep);
         // append suffix
@@ -293,7 +295,6 @@
     /**
      * Returns the subquery params if the comparison value is a DBCommand expression
      * @return the subquery params or null
-     */
     @Override
     public Object[] getSubqueryParams()
     {
@@ -302,6 +303,7 @@
         // nothing
         return null;
     }
+     */
 
     /**
      * Returns whether the constraint should replace another one or not.
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareExpr.java
index 88a4dcf..40a3395 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/compare/DBCompareExpr.java
@@ -77,11 +77,4 @@
      */
     public abstract DBCompareExpr copy(DBCommand newCmd); 
 
-    /**
-     * Returns the subquery Params
-     * Valid only directly after addSQL() has been called! 
-     * @return the subquery params;
-     */
-    public abstract Object[] getSubqueryParams();
-
 }
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 e5cdeed..be6f452 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
@@ -127,12 +127,12 @@
     /**
      * Returns the subquery params if the compare expression
      * @return the subquery params or null
-     */
     @Override
     public Object[] getSubqueryParams()
     {
         return expr.getSubqueryParams();
     }
+     */
     
     /**
      * Returns whether the constraint should replace another one or not.
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 41dfc9f..d3a274c 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
@@ -94,11 +94,11 @@
     /**

      * Returns the subquery params if the compare expression

      * @return the subquery params or null

-     */

     @Override

     public Object[] getSubqueryParams()

     {

         return wrapped.getSubqueryParams();

     }

+     */

     

 }

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 76bb52e..a3528b7 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
@@ -153,13 +153,13 @@
     /**
      * Returns the subquery params if the compare expression
      * @return the subquery params or null
-     */
     @Override
     public Object[] getSubqueryParams()
     {
         // none
         return cmd.getParamValues();
     }
+     */
    
     /**
      * Returns wheter the constraint should replace another one or not.
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 9904cb8..bc27bfb 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
@@ -26,7 +26,6 @@
 import org.apache.empire.db.DBCommand;

 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;

@@ -272,7 +271,6 @@
      * Valid only directly after addSQL() has been called! 

      * @param which: both (==0) | left (<=0) | right (>=0)   

      * @return the subquery params;

-     */

     @Override

     public Object[] getSubqueryParams(int which)

     {

@@ -292,6 +290,7 @@
         }

         return (leftParams!=null ? leftParams : rightParams);

     }

+     */

 

     /**

      * Compares two DBJoinExpr objects.

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 cd49456..3667854 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
@@ -25,7 +25,6 @@
 import org.apache.empire.db.DBCommand;
 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;
 
@@ -172,7 +171,6 @@
      * Valid only directly after addSQL() has been called!
      * @param which: both (==0) | left (<=0) | right (>=0)   
      * @return the subquery params;
-     */
     @Override
     public Object[] getSubqueryParams(int which)
     {
@@ -190,6 +188,7 @@
         }
         return (leftParams!=null ? leftParams : rightParams);
     }
+     */
 
     /**
      * Compares two DBJoinExpr objects.
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExpr.java
index 659a832..0ee4041 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/join/DBJoinExpr.java
@@ -104,7 +104,7 @@
      * @param which: both (==0) | left (<=0) | right (>=0)   
      * @return the subquery params;
      */
-    public abstract Object[] getSubqueryParams(int which);
+    // public abstract Object[] getSubqueryParams(int which);
     
     /**
      * This function swaps the left and the right statements of the join expression.
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 cc4105a..84f1249 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
@@ -58,6 +58,12 @@
     void detachDatabase(DBDatabase db, Connection conn);
     
     /**
+     * This function creates a DBSQLBuilder for this DBMS
+     * @return a DBMS specific DBSQLBuilder object
+     */
+    DBSQLBuilder createSQLBuilder();
+
+    /**
      * This function creates a DBCommand for this DBMS
      * @param autoPrepareStmt whether or not the Command should automatically generate a prepared statement (using ?)
      * @return a DBMS specific DBCommand object
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 f5314d8..0067880 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
@@ -71,6 +71,8 @@
 public abstract class DBMSHandlerBase implements DBMSHandler
 {
     private static final Logger log = LoggerFactory.getLogger(DBMSHandler.class);
+    
+    protected static final char     TEXT_DELIMITER       = '\'';
       
     // Illegal name chars and reserved SQL keywords
     protected static final char[]   ILLEGAL_NAME_CHARS   = new char[] { '@', '?', '>', '=', '<', ';', ':', 
@@ -87,9 +89,20 @@
     protected String SEQUENCE_NAME_SUFFIX = "_SEQ";
     
     /**
+     * DBMSBuilder
+     * A Default DBSQLBuilder implementation with no additional features
+     */
+    public static final class DBMSBuilder extends DBSQLBuilder 
+    {
+        protected DBMSBuilder(DBMSHandler dbms)
+        {
+            super(dbms);
+        }
+    }
+    
+    /**
      * DBMSCommand
      * A Default DBCommand implementation with no additional features
-     * @author doebele
      */
     public static final class DBMSCommand extends DBCommand 
     {
@@ -247,7 +260,7 @@
         String schema   = db.getSchema();
         String linkName = db.getLinkName();
         // build the statement
-        DBSQLBuilder sql = new DBSQLBuilder(this);
+        DBSQLBuilder sql = createSQLBuilder();
         sql.append("SELECT count(*) from ");
         if (schema != null)
         {   // Add Schema
@@ -290,6 +303,16 @@
     }
 
     /**
+     * This function creates a DBSQLBuilder for this DBMS
+     * @return a DBMS specific DBSQLBuilder object
+     */
+    @Override
+    public DBSQLBuilder createSQLBuilder()
+    {
+        return new DBMSBuilder(this);
+    }
+
+    /**
      * This function creates a DBCommand derived object this database
      * @param db the database for which to create a command object for
      * @return a DBCommand object
@@ -548,7 +571,7 @@
             case CHAR:
             case CLOB:
             case UNIQUEID:
-                return getSQLTextString(type, value);
+                return getSQLStringLiteral(type, value);
             case BOOL:
                 // Get Boolean value   
                 boolean boolVal = false;
@@ -1054,21 +1077,20 @@
     /**
      * encodes Text values for an SQL command string.
      * @param type date type (can only be TEXT, CHAR, CLOB and UNIQUEID)
-     * @param value the text to be encoded
+     * @param text the text to be encoded
      * @return the encoded sql value
      */
-    protected String getSQLTextString(DataType type, Object value)
-    {
+    protected String getSQLStringLiteral(DataType type, Object value)
+    {   // text
         if (value==null)
-            return getSQLPhrase(DBSqlPhrase.SQL_NULL);
-        // text
+            return getSQLPhrase(DBSqlPhrase.SQL_NULL); 
         String text = value.toString();
-        StringBuilder valBuf = new StringBuilder(text.length()+2);
-        valBuf.append("'");
-        if (DBDatabase.EMPTY_STRING.equals(value)==false)
-            appendSQLTextValue(valBuf, text);
-        valBuf.append("'");
-        return valBuf.toString();
+        StringBuilder sql = new StringBuilder(text.length()+2);
+        sql.append(TEXT_DELIMITER);
+        if (DBDatabase.EMPTY_STRING.equals(text)==false)
+            appendSQLTextValue(sql, text);
+        sql.append(TEXT_DELIMITER);
+        return sql.toString();
     }
 
     /** 
@@ -1076,21 +1098,22 @@
      */
     protected void appendSQLTextValue(StringBuilder sql, String value)
     {
-        if (value.indexOf('\'') >= 0)
-        { // a routine to double up single quotes for SQL
-            int len = value.length();
-            for (int i = 0; i < len; i++)
-            {
-                if (value.charAt(i) == '\'')
-                    sql.append("''");
-                else
-                    sql.append(value.charAt(i));
-            }
-        } 
-        else
-        {
-            sql.append(value);
+        int pos = 0;
+        int delim;
+        // find delimiter
+        while ((delim = value.indexOf(TEXT_DELIMITER, pos))>=0)
+        {   // append
+            if (delim>pos)
+                sql.append(value.substring(pos, delim));
+            // double up
+            sql.append("''");
+            // next
+            pos = delim + 1;
         }
+        if (pos==0)
+            sql.append(value); // add entire string
+        else if (pos < value.length())
+            sql.append(value.substring(pos)); // add the rest
     }
 
     /**
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 22bb1bf..deba595 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
@@ -235,7 +235,7 @@
     @Override
     public Object getNextSequenceValue(DBDatabase db, String seqName, int minValue, Connection conn)
     { 	//Use Oracle Sequences
-        DBSQLBuilder sql = new DBSQLBuilder(this);
+        DBSQLBuilder sql = createSQLBuilder();
         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 d5c2eb7..af24c04 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
@@ -109,7 +109,7 @@
     {

         String seqName = dbms.getColumnSequenceName(column);

         // createSQL

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         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/MySQLDDLGenerator.java b/empire-db/src/main/java/org/apache/empire/dbms/mysql/MySQLDDLGenerator.java
index e3c90c9..25886a9 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
@@ -141,7 +141,7 @@
     @Override

     protected void createTable(DBTable t, DBSQLScript script)

     {

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         sql.append("-- creating table ");

         sql.append(t.getName());

         sql.append(" --\r\n");

@@ -217,7 +217,7 @@
         cmd.clearOrderBy();

 

         // Build String

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         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/DBMSHandlerOracle.java b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java
index 36d40fb..0f3c59d 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
@@ -345,7 +345,7 @@
     @Override
     public Object getNextSequenceValue(DBDatabase db, String seqName, int minValue, Connection conn)
     { // Use Oracle Sequences
-        DBSQLBuilder sql = new DBSQLBuilder(this);
+        DBSQLBuilder sql = createSQLBuilder();
         sql.append("SELECT ");
         db.appendQualifiedName(sql, seqName, null);
         sql.append(".NEXTVAL FROM DUAL");
@@ -372,7 +372,7 @@
         String seqName = StringUtils.toString(column.getDefaultValue());
         if (StringUtils.isEmpty(seqName))
             throw new InvalidArgumentException("column", column);
-        DBSQLBuilder sql = new DBSQLBuilder(this);
+        DBSQLBuilder sql = createSQLBuilder();
         column.getDatabase().appendQualifiedName(sql, seqName, null);
         sql.append(".NEXTVAL");
         return new DBValueExpr(column.getDatabase(), sql.toString(), DataType.UNKNOWN);
@@ -430,7 +430,7 @@
     public void appendEnableRelationStmt(DBRelation r, boolean enable, DBSQLScript script)
     {
         // ALTER TABLE {table.name} {ENABLE|DISABLE} CONSTRAINT {relation.name}
-        DBSQLBuilder sql = new DBSQLBuilder(this);
+        DBSQLBuilder sql = createSQLBuilder();
         sql.append("ALTER TABLE ");
         r.getForeignKeyTable().addSQL(sql, DBExpr.CTX_FULLNAME);
         sql.append(enable ? " ENABLE " : " DISABLE ");
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 7eebd61..800dc18 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
@@ -141,7 +141,7 @@
     {

         String seqName = dbms.getColumnSequenceName(column);

         // createSQL

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         sql.append("-- creating sequence for column ");

         sql.append(column.getFullName());

         sql.append(" --\r\n");

@@ -171,7 +171,7 @@
     {

         if (comment==null || comment.length()==0)

             return; // Nothing to do

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         sql.append("COMMENT ON ");

         sql.append(type);

         sql.append(" ");

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 a3644ed..39367e5 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
@@ -290,7 +290,7 @@
         {
             throw new InvalidArgumentException("column", column);
         }
-        DBSQLBuilder sql = new DBSQLBuilder(this);
+        DBSQLBuilder sql = createSQLBuilder();
         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 a4bd4fe..ea49328 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
@@ -93,10 +93,4 @@
         sql.append(" @@ ");
         this.right.addSQL(sql, context);
     }
-
-    @Override
-    public Object[] getSubqueryParams()
-    {
-        return null;
-    }
 }
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 4ed5d16..5a57531 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
@@ -153,7 +153,7 @@
     {

     	String seqName = dbms.getColumnSequenceName(column);

         // createSQL

-        DBSQLBuilder sql = new DBSQLBuilder(dbms);

+        DBSQLBuilder sql = dbms.createSQLBuilder();

         sql.append("-- creating sequence for column ");

         sql.append(column.getFullName());

         sql.append(" --\r\n");

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 2a8208f..bc3589b 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
@@ -56,7 +56,7 @@
 	@Override

 	protected void createTable(DBTable t, DBSQLScript script)

 	{

-		DBSQLBuilder sql = new DBSQLBuilder(dbms);

+		DBSQLBuilder sql = dbms.createSQLBuilder();

 		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 1527f04..6bd8f12 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
@@ -457,20 +457,18 @@
      * @see DBMSHandler#getSQLTextString(DataType type, Object value)
      */
     @Override
-    protected String getSQLTextString(DataType type, Object value)
-    {
+    protected String getSQLStringLiteral(DataType type, Object value)
+    {   // text
         if (value==null)
-            return getSQLPhrase(DBSqlPhrase.SQL_NULL);
-        // text
+            return getSQLPhrase(DBSqlPhrase.SQL_NULL); 
         String text = value.toString();
-        StringBuilder valBuf = new StringBuilder(text.length()+4);
+        StringBuilder sql = new StringBuilder(text.length()+2);
         // for SQLSERVER utf8 support, see EMPIREDB-122
-        valBuf.append((useUnicodePrefix) ? "N'" : "'");
-        if (DBDatabase.EMPTY_STRING.equals(value)==false)
-            appendSQLTextValue(valBuf, text);
-        valBuf.append("'");
-        return valBuf.toString();
-        
+        sql.append((useUnicodePrefix) ? "N'" : "'");
+        if (DBDatabase.EMPTY_STRING.equals(text)==false)
+            appendSQLTextValue(sql, text);
+        sql.append(TEXT_DELIMITER);
+        return sql.toString();
     }
     
     /**
@@ -559,7 +557,7 @@
     public void appendEnableRelationStmt(DBRelation r, boolean enable, DBSQLScript script)
     {
         // ALTER TABLE {table.name} {CHECK|NOCHECK} CONSTRAINT {relation.name}
-        DBSQLBuilder sql = new DBSQLBuilder(this);
+        DBSQLBuilder sql = createSQLBuilder();
         sql.append("ALTER TABLE ");
         r.getForeignKeyTable().addSQL(sql, DBExpr.CTX_FULLNAME);
         sql.append(enable ? " CHECK " : " NOCHECK ");
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 9992c77..8a67050 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
@@ -58,7 +58,7 @@
     @Test
     public void testAddSQL()
     {
-        DBSQLBuilder builder = new DBSQLBuilder(dbms);
+        DBSQLBuilder builder = dbms.createSQLBuilder();
         expr.addSQL(builder, 0);
         assertEquals("", builder.toString());
         expr.addSQL(builder, DBExpr.CTX_DEFAULT);
@@ -68,7 +68,7 @@
     @Test
     public void testAddSQLEmptyString()
     {
-        DBSQLBuilder builder = new DBSQLBuilder(dbms);
+        DBSQLBuilder builder = dbms.createSQLBuilder();
         DBSetExpr setExpr = new DBSetExpr(testDB.EMPLOYEE.FIRSTNAME, "");
         setExpr.addSQL(builder, DBExpr.CTX_DEFAULT);
         // Empire-DB by default sees '' as null
@@ -78,7 +78,7 @@
     @Test
     public void testAddSQLEmptyStringConstant()
     {
-        DBSQLBuilder builder = new DBSQLBuilder(dbms);
+        DBSQLBuilder builder = dbms.createSQLBuilder();
         DBSetExpr setExpr = new DBSetExpr(testDB.EMPLOYEE.FIRSTNAME, DBDatabase.EMPTY_STRING);
         setExpr.addSQL(builder, DBExpr.CTX_DEFAULT);
         assertEquals("FIRSTNAME=''", builder.toString());