*** misc/hsqldb/src/org/hsqldb/Collation.java	Thu Mar 31 10:34:36 2005
--- misc/build/hsqldb/src/org/hsqldb/Collation.java	Thu Mar 31 10:35:27 2005
***************
*** 1 ****
! dummy
--- 1,197 ----
! /* Copyright (c) 2001-2005, The HSQL Development Group
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms, with or without
!  * modification, are permitted provided that the following conditions are met:
!  *
!  * Redistributions of source code must retain the above copyright notice, this
!  * list of conditions and the following disclaimer.
!  *
!  * Redistributions in binary form must reproduce the above copyright notice,
!  * this list of conditions and the following disclaimer in the documentation
!  * and/or other materials provided with the distribution.
!  *
!  * Neither the name of the HSQL Development Group nor the names of its
!  * contributors may be used to endorse or promote products derived from this
!  * software without specific prior written permission.
!  *
!  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
!  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
!  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
!  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
!  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
!  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
!  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
!  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
!  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
!  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
!  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!  */
! 
! 
! package org.hsqldb;
! 
! import org.hsqldb.lib.*;
! 
! import java.util.Locale;
! import java.text.Collator;
! 
! public class Collation {
! 
!     static final HashMap nameToJavaName = new HashMap(101);
! 
!     static {
!         nameToJavaName.put("Afrikaans", "af-ZA");
!         nameToJavaName.put("Amharic", "am-ET");
!         nameToJavaName.put("Arabic", "ar");
!         nameToJavaName.put("Assamese", "as-IN");
!         nameToJavaName.put("Azerbaijani_Latin", "az-AZ");
!         nameToJavaName.put("Azerbaijani_Cyrillic", "az-cyrillic");
!         nameToJavaName.put("Belarusian", "be-BY");
!         nameToJavaName.put("Bulgarian", "bg-BG");
!         nameToJavaName.put("Bengali", "bn-IN");
!         nameToJavaName.put("Tibetan", "bo-CN");
!         nameToJavaName.put("Bosnian", "bs-BA");
!         nameToJavaName.put("Catalan", "ca-ES");
!         nameToJavaName.put("Czech", "cs-CZ");
!         nameToJavaName.put("Welsh", "cy-GB");
!         nameToJavaName.put("Danish", "da-DK");
!         nameToJavaName.put("German", "de-DE");
!         nameToJavaName.put("Greek", "el-GR");
!         nameToJavaName.put("Latin1_General", "en-US");
!         nameToJavaName.put("Spanish", "es-ES");
!         nameToJavaName.put("Estonian", "et-EE");
!         nameToJavaName.put("Basque", "eu");
!         nameToJavaName.put("Finnish", "fi-FI");
!         nameToJavaName.put("French", "fr-FR");
!         nameToJavaName.put("Guarani", "gn-PY");
!         nameToJavaName.put("Gujarati", "gu-IN");
!         nameToJavaName.put("Hausa", "ha-NG");
!         nameToJavaName.put("Hebrew", "he-IL");
!         nameToJavaName.put("Hindi", "hi-IN");
!         nameToJavaName.put("Croatian", "hr-HR");
!         nameToJavaName.put("Hungarian", "hu-HU");
!         nameToJavaName.put("Armenian", "hy-AM");
!         nameToJavaName.put("Indonesian", "id-ID");
!         nameToJavaName.put("Igbo", "ig-NG");
!         nameToJavaName.put("Icelandic", "is-IS");
!         nameToJavaName.put("Italian", "it-IT");
!         nameToJavaName.put("Inuktitut", "iu-CA");
!         nameToJavaName.put("Japanese", "ja-JP");
!         nameToJavaName.put("Georgian", "ka-GE");
!         nameToJavaName.put("Kazakh", "kk-KZ");
!         nameToJavaName.put("Khmer", "km-KH");
!         nameToJavaName.put("Kannada", "kn-IN");
!         nameToJavaName.put("Korean", "ko-KR");
!         nameToJavaName.put("Konkani", "kok-IN");
!         nameToJavaName.put("Kashmiri", "ks");
!         nameToJavaName.put("Kirghiz", "ky-KG");
!         nameToJavaName.put("Lao", "lo-LA");
!         nameToJavaName.put("Lithuanian", "lt-LT");
!         nameToJavaName.put("Latvian", "lv-LV");
!         nameToJavaName.put("Maori", "mi-NZ");
!         nameToJavaName.put("Macedonian", "mk-MK");
!         nameToJavaName.put("Malayalam", "ml-IN");
!         nameToJavaName.put("Mongolian", "mn-MN");
!         nameToJavaName.put("Manipuri", "mni-IN");
!         nameToJavaName.put("Marathi", "mr-IN");
!         nameToJavaName.put("Malay", "ms-MY");
!         nameToJavaName.put("Maltese", "mt-MT");
!         nameToJavaName.put("Burmese", "my-MM");
!         nameToJavaName.put("Danish_Norwegian", "nb-NO");
!         nameToJavaName.put("Nepali", "ne-NP");
!         nameToJavaName.put("Dutch", "nl-NL");
!         nameToJavaName.put("Norwegian", "nn-NO");
!         nameToJavaName.put("Oriya", "or-IN");
!         nameToJavaName.put("Punjabi", "pa-IN");
!         nameToJavaName.put("Polish", "pl-PL");
!         nameToJavaName.put("Pashto", "ps-AF");
!         nameToJavaName.put("Portuguese", "pt-PT");
!         nameToJavaName.put("Romanian", "ro-RO");
!         nameToJavaName.put("Russian", "ru-RU");
!         nameToJavaName.put("Sanskrit", "sa-IN");
!         nameToJavaName.put("Sindhi", "sd-IN");
!         nameToJavaName.put("Slovak", "sk-SK");
!         nameToJavaName.put("Slovenian", "sl-SI");
!         nameToJavaName.put("Somali", "so-SO");
!         nameToJavaName.put("Albanian", "sq-AL");
!         nameToJavaName.put("Serbian_Cyrillic", "sr-YU");
!         nameToJavaName.put("Serbian_Latin", "sh-BA");
!         nameToJavaName.put("Swedish", "sv-SE");
!         nameToJavaName.put("Swahili", "sw-KE");
!         nameToJavaName.put("Tamil", "ta-IN");
!         nameToJavaName.put("Telugu", "te-IN");
!         nameToJavaName.put("Tajik", "tg-TJ");
!         nameToJavaName.put("Thai", "th-TH");
!         nameToJavaName.put("Turkmen", "tk-TM");
!         nameToJavaName.put("Tswana", "tn-BW");
!         nameToJavaName.put("Turkish", "tr-TR");
!         nameToJavaName.put("Tatar", "tt-RU");
!         nameToJavaName.put("Ukrainian", "uk-UA");
!         nameToJavaName.put("Urdu", "ur-PK");
!         nameToJavaName.put("Uzbek_Latin", "uz-UZ");
!         nameToJavaName.put("Venda", "ven-ZA");
!         nameToJavaName.put("Vietnamese", "vi-VN");
!         nameToJavaName.put("Yoruba", "yo-NG");
!         nameToJavaName.put("Chinese", "zh-CN");
!         nameToJavaName.put("Zulu", "zu-ZA");
!     }
! 
!     String   name;
!     Collator collator;
! 
!     public org.hsqldb.lib.Iterator getCollationsIterator() {
!         return nameToJavaName.keySet().iterator();
!     }
! 
!     public org.hsqldb.lib.Iterator getLocalesIterator() {
!         return nameToJavaName.values().iterator();
!     }
! 
!     public void setCollationAsLocale() {
! 
!         Locale locale   = Locale.getDefault();
!         String language = locale.getDisplayLanguage(Locale.ENGLISH);
! 
!         try {
!             setCollation(language);
!         } catch (HsqlException e) {}
!     }
! 
!     void setCollation(String name) throws HsqlException {
! 
!         String jname = (String) Collation.nameToJavaName.get(name);
! 
!         if (jname == null) {
!             throw Trace.error(Trace.INVALID_COLLATION_NAME_NO_SUBCLASS);
!         }
! 
!         this.name = name;
! 
!         String[] parts    = StringUtil.split(jname, "-");
!         String   language = parts[0];
!         String   country  = parts.length == 2 ? parts[1]
!                                               : "";
!         Locale   l        = new Locale(language, country);
! 
!         collator = Collator.getInstance(l);
!     }
! 
!     /**
!      * returns -1, 0 or +1
!      */
!     int compare(String a, String b) {
! 
!         int i;
! 
!         if (collator == null) {
!             i = a.compareTo(b);
!         } else {
!             i = collator.compare(a, b);
!         }
! 
!         return (i == 0) ? 0
!                         : (i < 0 ? -1
!                                  : 1);
!     }
! }
*** misc/hsqldb/src/org/hsqldb/Column.java	Wed Mar  2 14:50:45 2005
--- misc/build/hsqldb/src/org/hsqldb/Column.java	Thu Mar 31 10:35:27 2005
***************
*** 90,100 ****
  // java.lang.Number values and new functions to choose type for promotion
  // fredt@users 20020401 - patch 455757 by galena@users (Michiel de Roo)
  // interpretation of TINYINT as Byte instead of Short
- // fredt@users 20020130 - patch 505356 by daniel_fiser@users
- // use of the current locale for string comparison (instead of posix)
- // turned off by default but can be applied accross the database by defining
- // sql.compare_in_locale=true in database.properties file
- // changes marked separately
  // fredt@users 20020130 - patch 491987 by jimbag@users
  // support for sql standard char and varchar. size is maintained as
  // defined in the DDL and trimming and padding takes place accordingly
--- 90,95 ----
***************
*** 203,208 ****
--- 198,211 ----
          return newCol;
      }
  
+     void setType(Column other) {
+ 
+         isNullable = other.isNullable;
+         colType    = other.colType;
+         colSize    = other.colSize;
+         colScale   = other.colScale;
+     }
+ 
      /**
       *  Is this the identity column in the table.
       *
***************
*** 627,639 ****
          }
      }
  
! // fredt@users 20020130 - patch 505356 by daniel_fiser@users
! // modified for performance and made optional
!     static boolean sql_compare_in_locale = false;
! 
!     public static void setCompareInLocal(boolean value) {
!         sql_compare_in_locale = value;
!     }
  
      /**
       *  Compare a with b and return int value as result.
--- 630,647 ----
          }
      }
  
! // boucherb@users 2003-09-25
! // TODO:  Maybe use //#ifdef tag or reflective static method attribute
! // instantiation to take advantage of String.compareToIgnoreCase when
! // available (JDK 1.2 and greater) during ANT build. That or perhaps
! // consider using either local character-wise comparison or first converting
! // to lower case and then to upper case. Sun states that the JDK 1.2 introduced
! // String.compareToIngnorCase() comparison involves calling
! // Character.toLowerCase(Character.toUpperCase()) on compared characters,
! // to correctly handle some caveats concering using only the one operation or
! // the other outside the ascii character range.
! // fredt@users 20020130 - patch 418022 by deforest@users
! // use of rtrim() to mimic SQL92 behaviour
  
      /**
       *  Compare a with b and return int value as result.
***************
*** 644,650 ****
       * @return result 1 if a>b, 0 if a=b, -1 if b>a
       * @throws  HsqlException
       */
!     static int compare(Object a, Object b, int type) throws HsqlException {
  
          int i = 0;
  
--- 652,659 ----
       * @return result 1 if a>b, 0 if a=b, -1 if b>a
       * @throws  HsqlException
       */
!     static int compare(Collation collation, Object a, Object b,
!                        int type) throws HsqlException {
  
          int i = 0;
  
***************
*** 670,713 ****
  
              case Types.VARCHAR :
              case Types.LONGVARCHAR :
!                 if (sql_compare_in_locale) {
!                     i = JavaSystem.CompareInLocale((String) a, (String) b);
!                 } else {
!                     i = ((String) a).compareTo((String) b);
!                 }
!                 break;
  
- // fredt@users 20020130 - patch 418022 by deforest@users
- // use of rtrim() to mimic SQL92 behaviour
              case Types.CHAR :
!                 if (sql_compare_in_locale) {
!                     i = JavaSystem.CompareInLocale(Library.rtrim((String) a),
!                                                    Library.rtrim((String) b));
!                 } else {
!                     i = (Library.rtrim((String) a)).compareTo(
!                         Library.rtrim((String) b));
!                 }
!                 break;
  
- // boucherb@users 2003-09-25
- // TODO:  Maybe use //#ifdef tag or reflective static method attribute
- // instantiation to take advantage of String.compareToIgnoreCase when
- // available (JDK 1.2 and greater) during ANT build. That or perhaps
- // consider using either local character-wise comparison or first converting
- // to lower case and then to upper case. Sun states that the JDK 1.2 introduced
- // String.compareToIngnorCase() comparison involves calling
- // Character.toLowerCase(Character.toUpperCase()) on compared characters,
- // to correctly handle some caveats concering using only the one operation or
- // the other outside the ascii character range.
              case Types.VARCHAR_IGNORECASE :
!                 if (sql_compare_in_locale) {
!                     i = JavaSystem.CompareInLocale(
!                         ((String) a).toUpperCase(),
!                         ((String) b).toUpperCase());
!                 } else {
!                     i = JavaSystem.CompareIngnoreCase((String) a, (String) b);
!                 }
!                 break;
  
              case Types.TINYINT :
              case Types.SMALLINT :
--- 679,693 ----
  
              case Types.VARCHAR :
              case Types.LONGVARCHAR :
!                 return collation.compare((String) a, (String) b);
  
              case Types.CHAR :
!                 return collation.compare(Library.rtrim((String) a),
!                                          Library.rtrim((String) b));
  
              case Types.VARCHAR_IGNORECASE :
!                 return collation.compare(((String) a).toUpperCase(),
!                                          ((String) b).toUpperCase());
  
              case Types.TINYINT :
              case Types.SMALLINT :
***************
*** 1072,1083 ****
                          return o;
                      }
  
!                     if (o instanceof java.sql.Time) {
                          return HsqlDateTime.getTimeString((java.sql.Time) o,
                                                            null);
                      }
  
!                     if (o instanceof java.sql.Timestamp) {
                          return HsqlDateTime.getTimestampString(
                              (java.sql.Timestamp) o, null);
                      }
--- 1052,1063 ----
                          return o;
                      }
  
!                     if (o instanceof Time) {
                          return HsqlDateTime.getTimeString((java.sql.Time) o,
                                                            null);
                      }
  
!                     if (o instanceof Timestamp) {
                          return HsqlDateTime.getTimestampString(
                              (java.sql.Timestamp) o, null);
                      }
***************
*** 1093,1103 ****
                      break;
  
                  case Types.TIME :
!                     if (o instanceof java.sql.Time) {
                          return HsqlDateTime.getNormalisedTime((Time) o);
                      }
  
!                     if (o instanceof java.sql.Timestamp) {
                          return HsqlDateTime.getNormalisedTime((Timestamp) o);
                      }
  
--- 1073,1083 ----
                      break;
  
                  case Types.TIME :
!                     if (o instanceof Time) {
                          return HsqlDateTime.getNormalisedTime((Time) o);
                      }
  
!                     if (o instanceof Timestamp) {
                          return HsqlDateTime.getNormalisedTime((Timestamp) o);
                      }
  
***************
*** 1112,1122 ****
                      break;
  
                  case Types.TIMESTAMP :
!                     if (o instanceof java.sql.Timestamp) {
                          return o;
                      }
  
!                     if (o instanceof java.sql.Time) {
                          return HsqlDateTime.getNormalisedTimestamp((Time) o);
                      }
  
--- 1092,1102 ----
                      break;
  
                  case Types.TIMESTAMP :
!                     if (o instanceof Timestamp) {
                          return o;
                      }
  
!                     if (o instanceof Time) {
                          return HsqlDateTime.getNormalisedTimestamp((Time) o);
                      }
  
***************
*** 1136,1142 ****
                              (java.sql.Date) o);
                      }
  
!                     if (o instanceof java.sql.Timestamp) {
                          return HsqlDateTime.getNormalisedDate((Timestamp) o);
                      }
  
--- 1116,1122 ----
                              (java.sql.Date) o);
                      }
  
!                     if (o instanceof Timestamp) {
                          return HsqlDateTime.getNormalisedDate((Timestamp) o);
                      }
  
***************
*** 1144,1150 ****
                          return HsqlDateTime.dateValue((String) o);
                      }
  
!                     if (o instanceof java.sql.Time) {
                          throw Trace.error(Trace.INVALID_CONVERSION,
                                            Types.getTypeString(type));
                      }
--- 1124,1130 ----
                          return HsqlDateTime.dateValue((String) o);
                      }
  
!                     if (o instanceof Time) {
                          throw Trace.error(Trace.INVALID_CONVERSION,
                                            Types.getTypeString(type));
                      }
***************
*** 1399,1405 ****
       * For numeric conversions, scale is always converted to target first,
       * then precision is imposed. No truncation is allowed. (fredt)
       */
!     public static Object convertObject(Object o, int type, int precision,
                                         int scale) throws HsqlException {
  
          if (precision == 0) {
--- 1379,1386 ----
       * For numeric conversions, scale is always converted to target first,
       * then precision is imposed. No truncation is allowed. (fredt)
       */
!     public static Object convertObject(Session session, Object o, int type,
!                                        int precision,
                                         int scale) throws HsqlException {
  
          if (precision == 0) {
***************
*** 1425,1435 ****
  
              case Types.NUMERIC :
              case Types.DECIMAL :
!                 if (!(o instanceof Number)) {
                      o = convertObject(o, type);
                  }
  
                  return enforceSize(o, type, precision, scale, true);
          }
  
          return convertObject(o, type);
--- 1406,1425 ----
  
              case Types.NUMERIC :
              case Types.DECIMAL :
!                 if (!(o instanceof BigDecimal)) {
                      o = convertObject(o, type);
                  }
  
                  return enforceSize(o, type, precision, scale, true);
+ 
+             case Types.TIMESTAMP :
+                 if (o instanceof Time) {
+                     long millis = session.currentDate.getTime()
+                                   + ((Time) o).getTime();
+ 
+                     return HsqlDateTime.getTimestamp(millis);
+                 }
+             default :
          }
  
          return convertObject(o, type);
***************
*** 1692,1698 ****
       * @param  type java.sql.Types int for a numeric type
       * @return relative width
       */
!     private static int getNumTypeWidth(int type) {
  
          switch (type) {
  
--- 1682,1688 ----
       * @param  type java.sql.Types int for a numeric type
       * @return relative width
       */
!     static int getNumTypeWidth(int type) {
  
          switch (type) {
  
*** misc/hsqldb/src/org/hsqldb/CompiledStatement.java	Wed Mar  2 14:50:45 2005
--- misc/build/hsqldb/src/org/hsqldb/CompiledStatement.java	Thu Mar 31 10:35:27 2005
***************
*** 165,171 ****
       * @param deleteCondition
       * @param parameters
       */
!     CompiledStatement(TableFilter targetFilter, Expression deleteCondition,
                        Expression[] params) throws HsqlException {
  
          this.targetFilter = targetFilter;
--- 165,172 ----
       * @param deleteCondition
       * @param parameters
       */
!     CompiledStatement(Database database, TableFilter targetFilter,
!                       Expression deleteCondition,
                        Expression[] params) throws HsqlException {
  
          this.targetFilter = targetFilter;
***************
*** 175,181 ****
              condition = new Expression(deleteCondition);
  
              condition.resolveTables(targetFilter);
!             condition.resolveTypes();
              targetFilter.setConditions(condition);
          }
  
--- 176,182 ----
              condition = new Expression(deleteCondition);
  
              condition.resolveTables(targetFilter);
!             condition.resolveTypes(database);
              targetFilter.setConditions(condition);
          }
  
***************
*** 193,200 ****
       * @param updateCondition
       * @param params
       */
!     CompiledStatement(TableFilter targetFilter, int[] columnMap,
!                       Expression[] columnValues, Expression updateCondition,
                        Expression[] params) throws HsqlException {
  
          this.targetFilter = targetFilter;
--- 194,202 ----
       * @param updateCondition
       * @param params
       */
!     CompiledStatement(Database database, TableFilter targetFilter,
!                       int[] columnMap, Expression[] columnValues,
!                       Expression updateCondition,
                        Expression[] params) throws HsqlException {
  
          this.targetFilter = targetFilter;
***************
*** 213,219 ****
                  cve.setTableColumnAttributes(targetTable, columnMap[i]);
              } else {
                  cve.resolveTables(targetFilter);
!                 cve.resolveTypes();
              }
          }
  
--- 215,221 ----
                  cve.setTableColumnAttributes(targetTable, columnMap[i]);
              } else {
                  cve.resolveTables(targetFilter);
!                 cve.resolveTypes(database);
              }
          }
  
***************
*** 221,227 ****
              condition = new Expression(updateCondition);
  
              condition.resolveTables(targetFilter);
!             condition.resolveTypes();
              targetFilter.setConditions(condition);
          }
  
--- 223,229 ----
              condition = new Expression(updateCondition);
  
              condition.resolveTables(targetFilter);
!             condition.resolveTypes(database);
              targetFilter.setConditions(condition);
          }
  
***************
*** 272,278 ****
       * @param select
       * @param params
       */
!     CompiledStatement(Table targetTable, int[] columnMap,
                        boolean[] checkColumns, Select select,
                        Expression[] params) throws HsqlException {
  
--- 274,280 ----
       * @param select
       * @param params
       */
!     CompiledStatement(Database database, Table targetTable, int[] columnMap,
                        boolean[] checkColumns, Select select,
                        Expression[] params) throws HsqlException {
  
***************
*** 285,291 ****
          resolveInsertParameterTypes();
  
          // set select result metadata etc.
!         select.prepareResult();
          setParameters(params);
  
          type = INSERT_SELECT;
--- 287,293 ----
          resolveInsertParameterTypes();
  
          // set select result metadata etc.
!         select.prepareResult(database);
          setParameters(params);
  
          type = INSERT_SELECT;
***************
*** 297,303 ****
       * @param select
       * @param params
       */
!     CompiledStatement(Select select,
                        Expression[] params) throws HsqlException {
  
          this.select = select;
--- 299,305 ----
       * @param select
       * @param params
       */
!     CompiledStatement(Database database, Select select,
                        Expression[] params) throws HsqlException {
  
          this.select = select;
***************
*** 312,318 ****
          }
  
          // set select result metadata etc.
!         select.prepareResult();
          setParameters(params);
  
          type = SELECT;
--- 314,320 ----
          }
  
          // set select result metadata etc.
!         select.prepareResult(database);
          setParameters(params);
  
          type = SELECT;
***************
*** 324,335 ****
       * @param expression
       * @param params
       */
!     CompiledStatement(Expression expression,
                        Expression[] params) throws HsqlException {
  
          this.expression = expression;
  
!         expression.resolveTypes();
  
          expression.paramMode = Expression.PARAM_OUT;
  
--- 326,337 ----
       * @param expression
       * @param params
       */
!     CompiledStatement(Database database, Expression expression,
                        Expression[] params) throws HsqlException {
  
          this.expression = expression;
  
!         expression.resolveTypes(database);
  
          expression.paramMode = Expression.PARAM_OUT;
  
***************
*** 382,392 ****
              Result r = s.getResult(session, sq.isExistsPredicate ? 1
                                                                   : 0);
  
!             if (sq.isInPredicate) {
!                 r.removeDuplicates(1);
              }
  
!             t.insert(r);
  
              sq.isMaterialised = true;
          }
--- 384,394 ----
              Result r = s.getResult(session, sq.isExistsPredicate ? 1
                                                                   : 0);
  
!             if (sq.uniqueRows) {
!                 r.removeDuplicates(session, 1);
              }
  
!             t.insertResult(session, r);
  
              sq.isMaterialised = true;
          }
*** misc/hsqldb/src/org/hsqldb/Constraint.java	Wed Mar  2 14:50:45 2005
--- misc/build/hsqldb/src/org/hsqldb/Constraint.java	Thu Mar 31 10:35:27 2005
***************
*** 344,349 ****
--- 344,360 ----
          return false;
      }
  
+     boolean hasColumn(int colIndex) {
+ 
+         if (constType == MAIN) {
+             return ArrayUtil.find(core.mainColArray, colIndex) != -1;
+         } else if (constType == FOREIGN_KEY) {
+             return ArrayUtil.find(core.mainColArray, colIndex) != -1;
+         }
+ 
+         return false;
+     }
+ 
  // fredt@users 20020225 - patch 1.7.0 by fredt - duplicate constraints
  
      /**
***************
*** 520,547 ****
              return core.refIndex.emptyIterator();
          }
  
- /*
-         // there must be no record in the 'slave' table
-         // sebastian@scienion -- dependent on forDelete | forUpdate
-         boolean noaction = forDelete ? core.deleteAction == NO_ACTION
-                                      : core.updateAction == NO_ACTION;
- 
-         if (noaction) {
-             if (core.refIndex.exists(row, core.mainColArray)) {
-                 throw Trace.error(Trace.INTEGRITY_CONSTRAINT_VIOLATION,
-                                   Trace.Constraint_violation, new Object[] {
-                     core.fkName.name, core.refTable.getName().name
-                 });
-             } else {
-                 return core.refIndex.emptyIterator();
-             }
-         } else {
-             return delete
-                    ? core.refIndex.findFirstRowForDelete(row,
-                        core.mainColArray)
-                    : core.refIndex.findFirstRow(row, core.mainColArray);
-         }
- */
          return delete
                 ? core.refIndex.findFirstRowForDelete(session, row,
                     core.mainColArray)
--- 531,536 ----
***************
*** 582,596 ****
       * table. Also returns true if any column covered by the foreign key
       * constraint has a null value.
       */
!     private static boolean hasReferencedRow(Object[] rowdata,
!             int[] rowColArray, Index mainIndex) throws HsqlException {
  
          if (Index.isNull(rowdata, rowColArray)) {
              return true;
          }
  
          // else a record must exist in the main index
!         return mainIndex.exists(null, rowdata, rowColArray);
      }
  
      /**
--- 571,586 ----
       * table. Also returns true if any column covered by the foreign key
       * constraint has a null value.
       */
!     private static boolean hasReferencedRow(Session session,
!             Object[] rowdata, int[] rowColArray,
!             Index mainIndex) throws HsqlException {
  
          if (Index.isNull(rowdata, rowColArray)) {
              return true;
          }
  
          // else a record must exist in the main index
!         return mainIndex.exists(session, rowdata, rowColArray);
      }
  
      /**
***************
*** 598,607 ****
       * checks all rows of a table to ensure they all have a corresponding
       * row in the main table.
       */
!     static void checkReferencedRows(Table table, int[] rowColArray,
                                      Index mainIndex) throws HsqlException {
  
!         RowIterator it = table.rowIterator(null);
  
          while (true) {
              Row row = it.next();
--- 588,598 ----
       * checks all rows of a table to ensure they all have a corresponding
       * row in the main table.
       */
!     static void checkReferencedRows(Session session, Table table,
!                                     int[] rowColArray,
                                      Index mainIndex) throws HsqlException {
  
!         RowIterator it = table.rowIterator(session);
  
          while (true) {
              Row row = it.next();
***************
*** 612,618 ****
  
              Object[] rowdata = row.getData();
  
!             if (!Constraint.hasReferencedRow(rowdata, rowColArray,
                                               mainIndex)) {
                  String colvalues = "";
  
--- 603,609 ----
  
              Object[] rowdata = row.getData();
  
!             if (!Constraint.hasReferencedRow(session, rowdata, rowColArray,
                                               mainIndex)) {
                  String colvalues = "";
  
*** misc/hsqldb/src/org/hsqldb/Database.java	Wed Mar  2 14:50:45 2005
--- misc/build/hsqldb/src/org/hsqldb/Database.java	Thu Mar 31 10:35:27 2005
***************
*** 152,157 ****
--- 152,158 ----
      private HashMap                hAlias;
      private boolean                bIgnoreCase;
      private boolean                bReferentialIntegrity;
+     public TxManager               txManager;
      public SessionManager          sessionManager;
      private HsqlDatabaseProperties databaseProperties;
      HsqlNameManager                nameManager;
***************
*** 160,165 ****
--- 161,167 ----
      DatabaseObjectNames            constraintNameList;
      public SequenceManager         sequenceManager;
      CompiledStatementManager       compiledStatementManager;
+     public Collation               collation;
  
      //
      public static final int DATABASE_ONLINE       = 1;
***************
*** 288,293 ****
--- 290,297 ----
              bReferentialIntegrity = true;
              sysUser               = userManager.createSysUser();
              sessionManager        = new SessionManager(this, sysUser);
+             txManager             = new TxManager();
+             collation             = new Collation();
              dInfo = DatabaseInformation.newDatabaseInformation(this);
  
              if (sType != DatabaseManager.S_MEM) {
***************
*** 1183,1189 ****
  
  // boucherb@users - 200403?? - patch 1.7.2 - metadata
  //------------------------------------------------------------------------------
-     private String uri;
  
      /**
       * Retrieves the uri portion of this object's in-process JDBC url.
--- 1187,1192 ----
*** misc/hsqldb/src/org/hsqldb/DatabaseCommandInterpreter.java	Wed Mar  2 14:50:46 2005
--- misc/build/hsqldb/src/org/hsqldb/DatabaseCommandInterpreter.java	Thu Mar 31 10:35:27 2005
***************
*** 752,787 ****
  // --
      }
  
      /**
       *  Responsible for handling the creation of table columns during the
       *  process of executing CREATE TABLE DDL statements.
       *
!      *  @param  t target table
       *  @return a Column object with indicated attributes
       *  @throws  HsqlException
       */
!     private Column processCreateColumn(Table t) throws HsqlException {
  
          boolean    isIdentity        = false;
          long       identityStart     = database.firstIdentity;
          long       identityIncrement = 1;
          boolean    isPrimaryKey      = false;
-         String     columnName;
-         boolean    isQuoted;
          String     typeName;
          int        type;
          int        length      = 0;
          int        scale       = 0;
          boolean    isNullable  = true;
          Expression defaultExpr = null;
!         String     token       = tokenizer.getString();
! 
!         columnName = token;
! 
!         Trace.check(!columnName.equals(Table.DEFAULT_PK),
!                     Trace.COLUMN_ALREADY_EXISTS, columnName);
  
-         isQuoted = tokenizer.wasQuotedIdentifier();
          typeName = tokenizer.getString();
          type     = Types.getTypeNr(typeName);
  
--- 752,791 ----
  // --
      }
  
+     private Column processCreateColumn() throws HsqlException {
+ 
+         String  token      = tokenizer.getString();
+         String  columnName = token;
+         boolean isQuoted   = tokenizer.wasQuotedIdentifier();
+         HsqlName hsqlName = database.nameManager.newHsqlName(columnName,
+             isQuoted);
+ 
+         return processCreateColumn(hsqlName);
+     }
+ 
      /**
       *  Responsible for handling the creation of table columns during the
       *  process of executing CREATE TABLE DDL statements.
       *
!      *  @param  hsqlName name of the column
       *  @return a Column object with indicated attributes
       *  @throws  HsqlException
       */
!     private Column processCreateColumn(HsqlName hsqlName)
!     throws HsqlException {
  
          boolean    isIdentity        = false;
          long       identityStart     = database.firstIdentity;
          long       identityIncrement = 1;
          boolean    isPrimaryKey      = false;
          String     typeName;
          int        type;
          int        length      = 0;
          int        scale       = 0;
          boolean    isNullable  = true;
          Expression defaultExpr = null;
!         String     token;
  
          typeName = tokenizer.getString();
          type     = Types.getTypeNr(typeName);
  
***************
*** 820,825 ****
--- 824,833 ----
              tokenizer.getThis(Token.T_CLOSEBRACKET);
          }
  
+         if (type == Types.FLOAT && length > 53) {
+             throw Trace.error(Trace.NUMERIC_VALUE_OUT_OF_RANGE);
+         }
+ 
          token = tokenizer.getString();
  
          if (token.equals(Token.T_DEFAULT)) {
***************
*** 891,900 ****
              throw Trace.error(Trace.UNEXPECTED_TOKEN, Token.T_DEFAULT);
          }
  
!         return new Column(
!             database.nameManager.newHsqlName(columnName, isQuoted),
!             isNullable, type, length, scale, isIdentity, identityStart,
!             identityIncrement, isPrimaryKey, defaultExpr);
      }
  
      /**
--- 899,907 ----
              throw Trace.error(Trace.UNEXPECTED_TOKEN, Token.T_DEFAULT);
          }
  
!         return new Column(hsqlName, isNullable, type, length, scale,
!                           isIdentity, identityStart, identityIncrement,
!                           isPrimaryKey, defaultExpr);
      }
  
      /**
***************
*** 913,919 ****
          Parser     parser = new Parser(session, database, tokenizer);
          Expression expr   = parser.readDefaultClause(type);
  
!         expr.resolveTypes();
  
          if (expr.getType() == Expression.VALUE
                  || (expr.getType() == Expression.FUNCTION
--- 920,926 ----
          Parser     parser = new Parser(session, database, tokenizer);
          Expression expr   = parser.readDefaultClause(type);
  
!         expr.resolveTypes(database);
  
          if (expr.getType() == Expression.VALUE
                  || (expr.getType() == Expression.FUNCTION
***************
*** 1179,1185 ****
                  break;
              }
  
!             Column newcolumn = processCreateColumn(t);
  
              t.addColumn(newcolumn);
  
--- 1186,1192 ----
                  break;
              }
  
!             Column newcolumn = processCreateColumn();
  
              t.addColumn(newcolumn);
  
***************
*** 1212,1226 ****
  
              Constraint primaryConst = (Constraint) tempConstraints.get(0);
  
!             if (primaryConst.constName != null) {
!                 database.indexNameList.addName(primaryConst.constName.name,
!                                                t.getName(),
!                                                Trace.INDEX_ALREADY_EXISTS);
!                 database.constraintNameList.addName(
!                     primaryConst.constName.name, t.getName(),
!                     Trace.CONSTRAINT_ALREADY_EXISTS);
              }
  
              t.createPrimaryKey(primaryConst.constName,
                                 primaryConst.core.mainColArray, true);
  
--- 1219,1234 ----
  
              Constraint primaryConst = (Constraint) tempConstraints.get(0);
  
!             if (primaryConst.constName == null) {
!                 primaryConst.constName = t.makeSysPKName();
              }
  
+             database.indexNameList.addName(primaryConst.constName.name,
+                                            t.getName(),
+                                            Trace.INDEX_ALREADY_EXISTS);
+             database.constraintNameList.addName(
+                 primaryConst.constName.name, t.getName(),
+                 Trace.CONSTRAINT_ALREADY_EXISTS);
              t.createPrimaryKey(primaryConst.constName,
                                 primaryConst.core.mainColArray, true);
  
***************
*** 1445,1458 ****
  
          Select select;
  
!         // do not accept LIMIT and ORDER BY - accept unions
!         select = parser.parseSelect(brackets, false, true);
  
          if (select.sIntoTable != null) {
              throw (Trace.error(Trace.TABLE_NOT_FOUND));
          }
  
!         select.prepareResult();
  
          View view = new View(database, viewHsqlName, tokenizer.getLastPart(),
                               colList);
--- 1453,1466 ----
  
          Select select;
  
!         // accept ORDER BY or ORDRY BY with LIMIT - accept unions
!         select = parser.parseSelect(brackets, true, false, true, true);
  
          if (select.sIntoTable != null) {
              throw (Trace.error(Trace.TABLE_NOT_FOUND));
          }
  
!         select.prepareResult(database);
  
          View view = new View(database, viewHsqlName, tokenizer.getLastPart(),
                               colList);
***************
*** 1699,1709 ****
                  return;
              }
              default : {
!                 throw Trace.error(Trace.UNEXPECTED_TOKEN, token);
              }
          }
      }
  
      /**
       * Responsible for handling tail of ALTER COLUMN ... RENAME ...
       * @param t table
--- 1707,1727 ----
                  return;
              }
              default : {
!                 tokenizer.back();
!                 processAlterColumnType(t, column);
              }
          }
      }
  
+     private void processAlterColumnType(Table table,
+                                         Column oldCol) throws HsqlException {
+ 
+         Column     newCol = processCreateColumn(oldCol.columnName);
+         TableWorks tw     = new TableWorks(session, table);
+ 
+         tw.reTypeColumn(oldCol, newCol);
+     }
+ 
      /**
       * Responsible for handling tail of ALTER COLUMN ... RENAME ...
       * @param t table
***************
*** 2115,2120 ****
--- 2133,2153 ----
  
                  break;
              }
+             case Token.DATABASE : {
+                 session.checkAdmin();
+                 session.checkDDLWrite();
+                 tokenizer.getThis(Token.T_COLLATION);
+ 
+                 String cname = tokenizer.getIdentifier();
+ 
+                 if (!tokenizer.wasQuotedIdentifier()) {
+                     throw Trace.error(Trace.INVALID_IDENTIFIER);
+                 }
+ 
+                 database.collation.setCollation(cname);
+ 
+                 break;
+             }
              default : {
                  throw Trace.error(Trace.UNEXPECTED_TOKEN, token);
              }
***************
*** 2534,2540 ****
  
          String token;
          int    colindex = t.getColumnCount();
!         Column column   = processCreateColumn(t);
  
          checkAddColumn(t, column);
  
--- 2567,2573 ----
  
          String token;
          int    colindex = t.getColumnCount();
!         Column column   = processCreateColumn();
  
          checkAddColumn(t, column);
  
***************
*** 2551,2557 ****
  
          TableWorks tableWorks = new TableWorks(session, t);
  
!         tableWorks.addOrDropColumn(column, colindex, 1);
  
          return;
      }
--- 2584,2590 ----
  
          TableWorks tableWorks = new TableWorks(session, t);
  
!         tableWorks.addDropRetypeColumn(column, colindex, 1);
  
          return;
      }
***************
*** 2578,2584 ****
  
          TableWorks tableWorks = new TableWorks(session, t);
  
!         tableWorks.addOrDropColumn(null, colindex, -1);
      }
  
      /**
--- 2611,2617 ----
  
          TableWorks tableWorks = new TableWorks(session, t);
  
!         tableWorks.addDropRetypeColumn(null, colindex, -1);
      }
  
      /**
*** misc/hsqldb/src/org/hsqldb/DatabaseInformationFull.java	Wed Mar  2 14:50:46 2005
--- misc/build/hsqldb/src/org/hsqldb/DatabaseInformationFull.java	Thu Mar 31 10:35:27 2005
***************
*** 289,295 ****
              row[ialias_schem]        = schem;
              row[ialias]              = alias;
  
!             t.insert(row);
          }
  
          // must have create/alter table rights to see domain aliases
--- 289,295 ----
              row[ialias_schem]        = schem;
              row[ialias]              = alias;
  
!             t.insertSys(row);
          }
  
          // must have create/alter table rights to see domain aliases
***************
*** 320,326 ****
                  row[ialias_schem]        = schem;
                  row[ialias]              = alias;
  
!                 t.insert(row);
              }
          }
  
--- 320,326 ----
                  row[ialias_schem]        = schem;
                  row[ialias]              = alias;
  
!                 t.insertSys(row);
              }
          }
  
***************
*** 451,457 ****
              row[ifree_count] = ValuePool.getInt(cache.getFreeBlockCount());
              row[ifree_pos]   = ValuePool.getLong(cache.getFileFreePos());
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 451,457 ----
              row[ifree_count] = ValuePool.getInt(cache.getFreeBlockCount());
              row[ifree_pos]   = ValuePool.getLong(cache.getFileFreePos());
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 573,579 ****
                  row[iprivilege] = privilege;
                  row[iis_grntbl] = isGrantable;
  
!                 t.insert(row);
              }
  
              classNames = ns.iterateAccessibleTriggerClassNames(granteeUser);
--- 573,579 ----
                  row[iprivilege] = privilege;
                  row[iis_grntbl] = isGrantable;
  
!                 t.insertSys(row);
              }
  
              classNames = ns.iterateAccessibleTriggerClassNames(granteeUser);
***************
*** 596,602 ****
                  row[iprivilege] = privilege;
                  row[iis_grntbl] = isGrantable;
  
!                 t.insert(row);
              }
          }
  
--- 596,602 ----
                  row[iprivilege] = privilege;
                  row[iis_grntbl] = isGrantable;
  
!                 t.insertSys(row);
              }
          }
  
***************
*** 656,708 ****
          row[0] = "SESSION_ID";
          row[1] = String.valueOf(session.getId());
  
!         t.insert(row);
  
          row    = t.getEmptyRowData();
          row[0] = "AUTOCOMMIT";
          row[1] = session.isAutoCommit() ? "TRUE"
                                          : "FALSE";
  
!         t.insert(row);
  
          row    = t.getEmptyRowData();
          row[0] = "USER";
          row[1] = session.getUsername();
  
!         t.insert(row);
  
          row    = t.getEmptyRowData();
          row[0] = "SESSION_READONLY";
          row[1] = session.isReadOnly() ? "TRUE"
                                        : "FALSE";
  
!         t.insert(row);
  
          row    = t.getEmptyRowData();
          row[0] = "DATABASE_READONLY";
          row[1] = database.databaseReadOnly ? "TRUE"
                                             : "FALSE";
  
!         t.insert(row);
  
          // fredt - value set by SET MAXROWS in SQL, not Statement.setMaxRows()
          row    = t.getEmptyRowData();
          row[0] = "MAXROWS";
          row[1] = String.valueOf(session.getSQLMaxRows());
  
!         t.insert(row);
  
          row    = t.getEmptyRowData();
          row[0] = "DATABASE";
          row[1] = database.getURI();
  
!         t.insert(row);
  
          row    = t.getEmptyRowData();
          row[0] = "IDENTITY";
          row[1] = String.valueOf(session.getLastIdentity());
  
!         t.insert(row);
          t.setDataReadOnly(true);
  
          return t;
--- 656,708 ----
          row[0] = "SESSION_ID";
          row[1] = String.valueOf(session.getId());
  
!         t.insertSys(row);
  
          row    = t.getEmptyRowData();
          row[0] = "AUTOCOMMIT";
          row[1] = session.isAutoCommit() ? "TRUE"
                                          : "FALSE";
  
!         t.insertSys(row);
  
          row    = t.getEmptyRowData();
          row[0] = "USER";
          row[1] = session.getUsername();
  
!         t.insertSys(row);
  
          row    = t.getEmptyRowData();
          row[0] = "SESSION_READONLY";
          row[1] = session.isReadOnly() ? "TRUE"
                                        : "FALSE";
  
!         t.insertSys(row);
  
          row    = t.getEmptyRowData();
          row[0] = "DATABASE_READONLY";
          row[1] = database.databaseReadOnly ? "TRUE"
                                             : "FALSE";
  
!         t.insertSys(row);
  
          // fredt - value set by SET MAXROWS in SQL, not Statement.setMaxRows()
          row    = t.getEmptyRowData();
          row[0] = "MAXROWS";
          row[1] = String.valueOf(session.getSQLMaxRows());
  
!         t.insertSys(row);
  
          row    = t.getEmptyRowData();
          row[0] = "DATABASE";
          row[1] = database.getURI();
  
!         t.insertSys(row);
  
          row    = t.getEmptyRowData();
          row[0] = "IDENTITY";
          row[1] = String.valueOf(session.getLastIdentity());
  
!         t.insertSys(row);
          t.setDataReadOnly(true);
  
          return t;
***************
*** 741,747 ****
       *     <LI>hsqldb.nio_data_file - whether cache uses nio mapped buffers
       *     <LI>hsqldb.original_version -
       *     <LI>hsqldb.schemas - whether to report synthetic schema values for compatibility
-      *     <LI>sql.compare_in_locale - is JVM Locale used in collations?
       *     <LI>sql.enforce_size - column length specifications enforced (truncate/pad)?
       *     <LI>sql.enforce_strict_size - column length specifications enforced strictly (raise exception on overflow)?
       *     <LI>textdb.all_quoted - default policy regarding whether to quote all character field values
--- 741,746 ----
***************
*** 823,829 ****
          row[ivalue] = props.getProperty("hsqldb.catalogs", "false");
          row[iclass] = "boolean";
  
!         t.insert(row);
  
          // hsqldb.schemas
          row         = t.getEmptyRowData();
--- 822,828 ----
          row[ivalue] = props.getProperty("hsqldb.catalogs", "false");
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // hsqldb.schemas
          row         = t.getEmptyRowData();
***************
*** 833,839 ****
          row[ivalue] = props.getProperty("hsqldb.schemas", "false");
          row[iclass] = "boolean";
  
!         t.insert(row);
  
          // sql.enforce_size
          row         = t.getEmptyRowData();
--- 832,838 ----
          row[ivalue] = props.getProperty("hsqldb.schemas", "false");
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // sql.enforce_size
          row         = t.getEmptyRowData();
***************
*** 843,849 ****
          row[ivalue] = props.getProperty("sql.enforce_size", "false");
          row[iclass] = "boolean";
  
!         t.insert(row);
  
          // sql.enforce_strict_size
          row         = t.getEmptyRowData();
--- 842,848 ----
          row[ivalue] = props.getProperty("sql.enforce_size", "false");
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // sql.enforce_strict_size
          row         = t.getEmptyRowData();
***************
*** 853,869 ****
          row[ivalue] = props.getProperty("sql.enforce_strict_size", "false");
          row[iclass] = "boolean";
  
!         t.insert(row);
! 
!         // sql.compare_in_locale
!         row         = t.getEmptyRowData();
!         row[iscope] = scope;
!         row[ins]    = nameSpace;
!         row[iname]  = "sql.compare_in_locale";
!         row[ivalue] = props.getProperty("sql.compare_in_locale", "false");
!         row[iclass] = "boolean";
! 
!         t.insert(row);
  
          // hsqldb.files_readonly
          row         = t.getEmptyRowData();
--- 852,858 ----
          row[ivalue] = props.getProperty("sql.enforce_strict_size", "false");
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // hsqldb.files_readonly
          row         = t.getEmptyRowData();
***************
*** 873,879 ****
          row[ivalue] = props.getProperty("hsqldb.files_readonly", "false");
          row[iclass] = "boolean";
  
!         t.insert(row);
  
          // hsqldb.first_identity
          row         = t.getEmptyRowData();
--- 862,868 ----
          row[ivalue] = props.getProperty("hsqldb.files_readonly", "false");
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // hsqldb.first_identity
          row         = t.getEmptyRowData();
***************
*** 883,889 ****
          row[ivalue] = props.getProperty("hsqldb.first_identity", "0");
          row[iclass] = "int";
  
!         t.insert(row);
  
          // hsqldb.compatible_version
          row         = t.getEmptyRowData();
--- 872,878 ----
          row[ivalue] = props.getProperty("hsqldb.first_identity", "0");
          row[iclass] = "int";
  
!         t.insertSys(row);
  
          // hsqldb.compatible_version
          row         = t.getEmptyRowData();
***************
*** 893,899 ****
          row[ivalue] = props.getProperty("hsqldb.compatible_version");
          row[iclass] = "java.lang.String";
  
!         t.insert(row);
  
          // hsqldb.cache_version
          row         = t.getEmptyRowData();
--- 882,888 ----
          row[ivalue] = props.getProperty("hsqldb.compatible_version");
          row[iclass] = "java.lang.String";
  
!         t.insertSys(row);
  
          // hsqldb.cache_version
          row         = t.getEmptyRowData();
***************
*** 903,909 ****
          row[ivalue] = props.getProperty(HsqlDatabaseProperties.CACHE_VERSION);
          row[iclass] = "java.lang.String";
  
!         t.insert(row);
  
          // hsqldb.original_version
          row         = t.getEmptyRowData();
--- 892,898 ----
          row[ivalue] = props.getProperty(HsqlDatabaseProperties.CACHE_VERSION);
          row[iclass] = "java.lang.String";
  
!         t.insertSys(row);
  
          // hsqldb.original_version
          row         = t.getEmptyRowData();
***************
*** 913,919 ****
          row[ivalue] = props.getProperty("hsqldb.original_version");
          row[iclass] = "java.lang.String";
  
!         t.insert(row);
  
          // hsqldb.cache_scale
          row         = t.getEmptyRowData();
--- 902,908 ----
          row[ivalue] = props.getProperty("hsqldb.original_version");
          row[iclass] = "java.lang.String";
  
!         t.insertSys(row);
  
          // hsqldb.cache_scale
          row         = t.getEmptyRowData();
***************
*** 923,929 ****
          row[ivalue] = props.getProperty("hsqldb.cache_scale");
          row[iclass] = "int";
  
!         t.insert(row);
  
          // hsqldb.cache_file_scale
          row         = t.getEmptyRowData();
--- 912,918 ----
          row[ivalue] = props.getProperty("hsqldb.cache_scale");
          row[iclass] = "int";
  
!         t.insertSys(row);
  
          // hsqldb.cache_file_scale
          row         = t.getEmptyRowData();
***************
*** 934,940 ****
              props.getProperty(HsqlDatabaseProperties.CACHE_FILE_SCALE);
          row[iclass] = "int";
  
!         t.insert(row);
  
          // hsqldb.cache_size_scale
          row         = t.getEmptyRowData();
--- 923,929 ----
              props.getProperty(HsqlDatabaseProperties.CACHE_FILE_SCALE);
          row[iclass] = "int";
  
!         t.insertSys(row);
  
          // hsqldb.cache_size_scale
          row         = t.getEmptyRowData();
***************
*** 944,950 ****
          row[ivalue] = props.getProperty("hsqldb.cache_size_scale");
          row[iclass] = "int";
  
!         t.insert(row);
  
          // hsqldb.max_nio_scale
          row         = t.getEmptyRowData();
--- 933,939 ----
          row[ivalue] = props.getProperty("hsqldb.cache_size_scale");
          row[iclass] = "int";
  
!         t.insertSys(row);
  
          // hsqldb.max_nio_scale
          row         = t.getEmptyRowData();
***************
*** 954,960 ****
          row[ivalue] = props.getProperty("hsqldb.max_nio_scale");
          row[iclass] = "int";
  
!         t.insert(row);
  
          // hsqldb.nio_data_file
          row         = t.getEmptyRowData();
--- 943,949 ----
          row[ivalue] = props.getProperty("hsqldb.max_nio_scale");
          row[iclass] = "int";
  
!         t.insertSys(row);
  
          // hsqldb.nio_data_file
          row         = t.getEmptyRowData();
***************
*** 964,970 ****
          row[ivalue] = props.getProperty("hsqldb.nio_data_file");
          row[iclass] = "boolean";
  
!         t.insert(row);
  
          // textdb.all_quoted
          row         = t.getEmptyRowData();
--- 953,959 ----
          row[ivalue] = props.getProperty("hsqldb.nio_data_file");
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // textdb.all_quoted
          row         = t.getEmptyRowData();
***************
*** 974,980 ****
          row[ivalue] = props.getProperty("textdb.all_quoted", "false");
          row[iclass] = "boolean";
  
!         t.insert(row);
  
          // textdb.cache_scale
          row         = t.getEmptyRowData();
--- 963,969 ----
          row[ivalue] = props.getProperty("textdb.all_quoted", "false");
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // textdb.cache_scale
          row         = t.getEmptyRowData();
***************
*** 984,990 ****
          row[ivalue] = props.getProperty("textdb.cache_scale", "10");
          row[iclass] = "int";
  
!         t.insert(row);
  
          // textdb.cache_size_scale
          row         = t.getEmptyRowData();
--- 973,979 ----
          row[ivalue] = props.getProperty("textdb.cache_scale", "10");
          row[iclass] = "int";
  
!         t.insertSys(row);
  
          // textdb.cache_size_scale
          row         = t.getEmptyRowData();
***************
*** 994,1000 ****
          row[ivalue] = props.getProperty("textdb.cache_size_scale", "12");
          row[iclass] = "int";
  
!         t.insert(row);
  
          // textdb.ignore_first
          row         = t.getEmptyRowData();
--- 983,989 ----
          row[ivalue] = props.getProperty("textdb.cache_size_scale", "12");
          row[iclass] = "int";
  
!         t.insertSys(row);
  
          // textdb.ignore_first
          row         = t.getEmptyRowData();
***************
*** 1004,1010 ****
          row[ivalue] = props.getProperty("textdb.ignore_first", "false");
          row[iclass] = "boolean";
  
!         t.insert(row);
  
          // textdb.quoted
          row         = t.getEmptyRowData();
--- 993,999 ----
          row[ivalue] = props.getProperty("textdb.ignore_first", "false");
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // textdb.quoted
          row         = t.getEmptyRowData();
***************
*** 1014,1020 ****
          row[ivalue] = props.getProperty("textdb.quoted", "true");
          row[iclass] = "boolean";
  
!         t.insert(row);
  
          // textdb.fs
          row         = t.getEmptyRowData();
--- 1003,1009 ----
          row[ivalue] = props.getProperty("textdb.quoted", "true");
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // textdb.fs
          row         = t.getEmptyRowData();
***************
*** 1032,1038 ****
          row[ivalue] = props.getProperty("textdb.vs", ",");
          row[iclass] = "java.lang.String";
  
!         t.insert(row);
  
          // textdb.lvs
          row         = t.getEmptyRowData();
--- 1021,1027 ----
          row[ivalue] = props.getProperty("textdb.vs", ",");
          row[iclass] = "java.lang.String";
  
!         t.insertSys(row);
  
          // textdb.lvs
          row         = t.getEmptyRowData();
***************
*** 1042,1048 ****
          row[ivalue] = props.getProperty("textdb.lvs", ",");
          row[iclass] = "java.lang.String";
  
!         t.insert(row);
  
          // textdb.encoding
          row         = t.getEmptyRowData();
--- 1031,1037 ----
          row[ivalue] = props.getProperty("textdb.lvs", ",");
          row[iclass] = "java.lang.String";
  
!         t.insertSys(row);
  
          // textdb.encoding
          row         = t.getEmptyRowData();
***************
*** 1052,1058 ****
          row[ivalue] = props.getProperty("textdb.encoding", "ASCII");
          row[iclass] = "java.lang.String";
  
!         t.insert(row);
  
          // hsqldb.gc_interval
          row         = t.getEmptyRowData();
--- 1041,1047 ----
          row[ivalue] = props.getProperty("textdb.encoding", "ASCII");
          row[iclass] = "java.lang.String";
  
!         t.insertSys(row);
  
          // hsqldb.gc_interval
          row         = t.getEmptyRowData();
***************
*** 1062,1068 ****
          row[ivalue] = props.getProperty("hsqldb.gc_interval", "0");
          row[iclass] = "int";
  
!         t.insert(row);
  
          // Now get a snapshot of the properties that may change over
          // the lifetime of the session
--- 1051,1057 ----
          row[ivalue] = props.getProperty("hsqldb.gc_interval", "0");
          row[iclass] = "int";
  
!         t.insertSys(row);
  
          // Now get a snapshot of the properties that may change over
          // the lifetime of the session
***************
*** 1077,1083 ****
          row[ivalue] = "" + database.logger.getLogSize();
          row[iclass] = "int";
  
!         t.insert(row);
  
          row         = t.getEmptyRowData();
          row[iscope] = scope;
--- 1066,1072 ----
          row[ivalue] = "" + database.logger.getLogSize();
          row[iclass] = "int";
  
!         t.insertSys(row);
  
          row         = t.getEmptyRowData();
          row[iscope] = scope;
***************
*** 1092,1098 ****
  
          row[iclass] = "java.lang.String";
  
!         t.insert(row);
  
          // write delay
          row         = t.getEmptyRowData();
--- 1081,1087 ----
  
          row[iclass] = "java.lang.String";
  
!         t.insertSys(row);
  
          // write delay
          row         = t.getEmptyRowData();
***************
*** 1102,1108 ****
          row[ivalue] = "" + database.logger.getWriteDelay();
          row[iclass] = "int";
  
!         t.insert(row);
  
          // ignore case
          row         = t.getEmptyRowData();
--- 1091,1097 ----
          row[ivalue] = "" + database.logger.getWriteDelay();
          row[iclass] = "int";
  
!         t.insertSys(row);
  
          // ignore case
          row         = t.getEmptyRowData();
***************
*** 1113,1119 ****
                                                : "false";
          row[iclass] = "boolean";
  
!         t.insert(row);
  
          // referential integrity
          row         = t.getEmptyRowData();
--- 1102,1108 ----
                                                : "false";
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // referential integrity
          row         = t.getEmptyRowData();
***************
*** 1124,1130 ****
                                                          : "false";
          row[iclass] = "boolean";
  
!         t.insert(row);
  
          // debug
          // oj@openoffice.org
--- 1113,1119 ----
                                                          : "false";
          row[iclass] = "boolean";
  
!         t.insertSys(row);
  
          // debug
          // oj@openoffice.org
***************
*** 1135,1141 ****
          row[ivalue] = "" + database.logger.appLog.getLevel();
          row[iclass] = "int";
  
!         t.insert(row);
          t.setDataReadOnly(true);
  
          return t;
--- 1124,1130 ----
          row[ivalue] = "" + database.logger.appLog.getLevel();
          row[iclass] = "int";
  
!         t.insertSys(row);
          t.setDataReadOnly(true);
  
          return t;
***************
*** 1224,1230 ****
                  ValuePool.getLong(s.getLastIdentity().longValue());
              row[it_size] = ValuePool.getInt(s.getTransactionSize());
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 1213,1219 ----
                  ValuePool.getLong(s.getLastIdentity().longValue());
              row[it_size] = ValuePool.getInt(s.getTransactionSize());
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 1426,1432 ****
                  row[iid] = ValuePool.getBoolean(table.isDescDataSource());
              }
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 1415,1421 ----
                  row[iid] = ValuePool.getBoolean(table.isDescDataSource());
              }
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 1504,1510 ****
                  ' ').append("a.").append("TABLE_NAME").append('=').append(
                  "b.").append("TABLE_NAME").toString());
  
!         t.insert(rs);
          t.setDataReadOnly(true);
  
          return t;
--- 1493,1499 ----
                  ' ').append("a.").append("TABLE_NAME").append('=').append(
                  "b.").append("TABLE_NAME").toString());
  
!         t.insertSys(rs);
          t.setDataReadOnly(true);
  
          return t;
***************
*** 1693,1699 ****
                      row[iaction_type]       = actionType;
                      row[itrigger_body]      = triggerBody;
  
!                     t.insert(row);
                  }
              }
          }
--- 1682,1688 ----
                      row[iaction_type]       = actionType;
                      row[itrigger_body]      = triggerBody;
  
!                     t.insertSys(row);
                  }
              }
          }
***************
*** 2010,2016 ****
              row[iiupd]  = "NO";
              row[ivalid] = Boolean.TRUE;
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 1999,2005 ----
              row[iiupd]  = "NO";
              row[ivalid] = Boolean.TRUE;
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 2369,2375 ****
              "select 'SYS', 'PUBLIC', SEQUENCE_CATALOG, SEQUENCE_SCHEMA, "
              + "SEQUENCE_NAME, 'SEQUENCE', 'FALSE' from  SYSTEM_SEQUENCES");
  
!         t.insert(rs);
          t.setDataReadOnly(true);
  
          return t;
--- 2358,2364 ----
              "select 'SYS', 'PUBLIC', SEQUENCE_CATALOG, SEQUENCE_SCHEMA, "
              + "SEQUENCE_NAME, 'SEQUENCE', 'FALSE' from  SYSTEM_SEQUENCES");
  
!         t.insertSys(rs);
          t.setDataReadOnly(true);
  
          return t;
***************
*** 2518,2524 ****
                      });
                  }
  
!                 result.removeDuplicates();
  
                  iterator = result.iterator();
  
--- 2507,2514 ----
                      });
                  }
  
!                 result.removeDuplicates(
!                     database.sessionManager.getSysSession());
  
                  iterator = result.iterator();
  
***************
*** 2533,2539 ****
                      row[itab_name]   = resultRow[2];
                      row[itab_col]    = resultRow[3];
  
!                     t.insert(row);
                  }
              }
          }
--- 2523,2529 ----
                      row[itab_name]   = resultRow[2];
                      row[itab_col]    = resultRow[3];
  
!                     t.insertSys(row);
                  }
              }
          }
***************
*** 2692,2698 ****
                      row[ir_schem]    = ns.getSchemaName(method);
                      row[ir_name] = DINameSpace.getMethodSpecificName(method);
  
!                     t.insert(row);
                  }
              }
          }
--- 2682,2688 ----
                      row[ir_schem]    = ns.getSchemaName(method);
                      row[ir_name] = DINameSpace.getMethodSpecificName(method);
  
!                     t.insertSys(row);
                  }
              }
          }
***************
*** 2764,2770 ****
              + "CONSTRAINT_NAME, TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME "
              + "from SYSTEM_CHECK_COLUMN_USAGE");
  
!         t.insert(rs);
          t.setDataReadOnly(true);
  
          return t;
--- 2754,2760 ----
              + "CONSTRAINT_NAME, TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME "
              + "from SYSTEM_CHECK_COLUMN_USAGE");
  
!         t.insertSys(rs);
          t.setDataReadOnly(true);
  
          return t;
***************
*** 2949,2955 ****
                  row[iis_defr]    = "NO";
                  row[iinit_defr]  = "NO";
  
!                 t.insert(row);
              }
  
              constraints     = table.getConstraints();
--- 2939,2945 ----
                  row[iis_defr]    = "NO";
                  row[iinit_defr]  = "NO";
  
!                 t.insertSys(row);
              }
  
              constraints     = table.getConstraints();
***************
*** 3008,3014 ****
              row[iis_defr]    = "NO";
              row[iinit_defr]  = "NO";
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 2998,3004 ----
              row[iis_defr]    = "NO";
              row[iinit_defr]  = "NO";
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 3079,3085 ****
              + "VIEW_NAME, TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME "
              + "from SYSTEM_VIEW_COLUMN_USAGE");
  
!         t.insert(rs);
          t.setDataReadOnly(true);
  
          return t;
--- 3069,3075 ----
              + "VIEW_NAME, TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME "
              + "from SYSTEM_VIEW_COLUMN_USAGE");
  
!         t.insertSys(rs);
          t.setDataReadOnly(true);
  
          return t;
***************
*** 3227,3233 ****
                  });
              }
  
!             result.removeDuplicates();
  
              iterator = result.iterator();
  
--- 3217,3223 ----
                  });
              }
  
!             result.removeDuplicates(database.sessionManager.getSysSession());
  
              iterator = result.iterator();
  
***************
*** 3242,3248 ****
                  row[it_name]  = resultRow[2];
                  row[it_cname] = resultRow[3];
  
!                 t.insert(row);
              }
          }
  
--- 3232,3238 ----
                  row[it_name]  = resultRow[2];
                  row[it_cname] = resultRow[3];
  
!                 t.insertSys(row);
              }
          }
  
***************
*** 3392,3398 ****
                  row[ir_schem] = ns.getSchemaName(method);
                  row[ir_name]  = DINameSpace.getMethodSpecificName(method);
  
!                 t.insert(row);
              }
          }
  
--- 3382,3388 ----
                  row[ir_schem] = ns.getSchemaName(method);
                  row[ir_name]  = DINameSpace.getMethodSpecificName(method);
  
!                 t.insertSys(row);
              }
          }
  
***************
*** 3473,3479 ****
          row[isn]        = specificName;
          row[iseq]       = sequence;
  
!         t.insert(row);
  
          if (l != null) {
              int size = l.size();
--- 3463,3469 ----
          row[isn]        = specificName;
          row[iseq]       = sequence;
  
!         t.insertSys(row);
  
          if (l != null) {
              int size = l.size();
***************
*** 3497,3503 ****
                  row[isn]        = specificName;
                  row[iseq]       = sequence;
  
!                 t.insert(row);
              }
          }
      }
--- 3487,3493 ----
                  row[isn]        = specificName;
                  row[iseq]       = sequence;
  
!                 t.insertSys(row);
              }
          }
      }
***************
*** 3560,3566 ****
          row[iporigin]      = origin;
          row[isn]           = specificName;
  
!         t.insert(row);
  
          if (l != null) {
              int size = l.size();
--- 3550,3556 ----
          row[iporigin]      = origin;
          row[isn]           = specificName;
  
!         t.insertSys(row);
  
          if (l != null) {
              int size = l.size();
***************
*** 3579,3585 ****
                  row[iporigin]      = "ALIAS";
                  row[isn]           = specificName;
  
!                 t.insert(row);
              }
          }
      }
--- 3569,3575 ----
                  row[iporigin]      = "ALIAS";
                  row[isn]           = specificName;
  
!                 t.insertSys(row);
              }
          }
      }
*** misc/hsqldb/src/org/hsqldb/DatabaseInformationMain.java	Wed Mar  2 14:50:47 2005
--- misc/build/hsqldb/src/org/hsqldb/DatabaseInformationMain.java	Thu Mar 31 10:35:27 2005
***************
*** 864,870 ****
                  row[inullable]       = ti.getColNullability(i);
                  row[iinKey]          = inKey;
  
!                 t.insert(row);
              }
          }
  
--- 864,870 ----
                  row[inullable]       = ti.getColNullability(i);
                  row[iinKey]          = inKey;
  
!                 t.insertSys(row);
              }
          }
  
***************
*** 912,918 ****
              row    = t.getEmptyRowData();
              row[0] = (String) catalogs.next();
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 912,918 ----
              row    = t.getEmptyRowData();
              row[0] = (String) catalogs.next();
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 985,991 ****
              + "a.GRANTOR, a.GRANTEE, a.PRIVILEGE, a.IS_GRANTABLE "
              + "from  SYSTEM_TABLEPRIVILEGES a, SYSTEM_COLUMNS b where a.TABLE_NAME = b.TABLE_NAME;");
  
!         t.insert(rs);
          t.setDataReadOnly(true);
  
          return t;
--- 985,991 ----
              + "a.GRANTOR, a.GRANTEE, a.PRIVILEGE, a.IS_GRANTABLE "
              + "from  SYSTEM_TABLEPRIVILEGES a, SYSTEM_COLUMNS b where a.TABLE_NAME = b.TABLE_NAME;");
  
!         t.insertSys(rs);
          t.setDataReadOnly(true);
  
          return t;
***************
*** 1144,1150 ****
                  row[iis_nullable]       = ti.getColIsNullable(i);
                  row[itype_sub]          = ti.getColDataTypeSub(i);
  
!                 t.insert(row);
              }
          }
  
--- 1144,1150 ----
                  row[iis_nullable]       = ti.getColIsNullable(i);
                  row[itype_sub]          = ti.getColDataTypeSub(i);
  
!                 t.insertSys(row);
              }
          }
  
***************
*** 1360,1366 ****
                  row[ipk_name]        = pkName;
                  row[ideferrability]  = deferrability;
  
!                 t.insert(row);
              }
          }
  
--- 1360,1366 ----
                  row[ipk_name]        = pkName;
                  row[ideferrability]  = deferrability;
  
!                 t.insertSys(row);
              }
          }
  
***************
*** 1531,1537 ****
                      row[ipages]            = pages;
                      row[ifilter_condition] = filterCondition;
  
!                     t.insert(row);
                  }
              }
          }
--- 1531,1537 ----
                      row[ipages]            = pages;
                      row[ifilter_condition] = filterCondition;
  
!                     t.insertSys(row);
                  }
              }
          }
***************
*** 1649,1655 ****
                  row[ikey_seq]     = ValuePool.getInt(j + 1);
                  row[ipk_name]     = primaryKeyName;
  
!                 t.insert(row);
              }
          }
  
--- 1649,1655 ----
                  row[ikey_seq]     = ValuePool.getInt(j + 1);
                  row[ipk_name]     = primaryKeyName;
  
!                 t.insertSys(row);
              }
          }
  
***************
*** 1869,1875 ****
              row[0] = schemas.next();
              row[1] = ns.getCatalogName(row[0]);
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 1869,1875 ----
              row[0] = schemas.next();
              row[1] = ns.getCatalogName(row[0]);
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 2001,2007 ****
                      row[iprivilege]    = privilege;
                      row[iis_grantable] = isGrantable;
  
!                     t.insert(row);
                  }
              }
          }
--- 2001,2007 ----
                      row[iprivilege]    = privilege;
                      row[iis_grantable] = isGrantable;
  
!                     t.insertSys(row);
                  }
              }
          }
***************
*** 2132,2138 ****
              row[ihsqldb_type] = ti.getHsqlType();
              row[iread_only]   = ti.isReadOnly();
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 2132,2138 ----
              row[ihsqldb_type] = ti.getHsqlType();
              row[iread_only]   = ti.isReadOnly();
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 2196,2202 ****
              row    = t.getEmptyRowData();
              row[0] = tableTypes[i];
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 2196,2202 ----
              row    = t.getEmptyRowData();
              row[0] = tableTypes[i];
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 2303,2309 ****
              + "MAXIMUM_SCALE, SQL_DATA_TYPE, SQL_DATETIME_SUB, NUM_PREC_RADIX, TYPE_SUB "
              + "from SYSTEM_ALLTYPEINFO  where AS_TAB_COL = true;");
  
!         t.insert(rs);
          t.setDataReadOnly(true);
  
          return t;
--- 2303,2309 ----
              + "MAXIMUM_SCALE, SQL_DATA_TYPE, SQL_DATETIME_SUB, NUM_PREC_RADIX, TYPE_SUB "
              + "from SYSTEM_ALLTYPEINFO  where AS_TAB_COL = true;");
  
!         t.insertSys(rs);
          t.setDataReadOnly(true);
  
          return t;
***************
*** 2630,2636 ****
              //------------------------------------------
              row[itype_sub] = ti.getDataTypeSub();
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 2630,2636 ----
              //------------------------------------------
              row[itype_sub] = ti.getDataTypeSub();
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 2678,2684 ****
              row[0] = user.getName();
              row[1] = ValuePool.getBoolean(user.isAdmin());
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 2678,2684 ----
              row[0] = user.getName();
              row[1] = ValuePool.getBoolean(user.isAdmin());
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 2805,2811 ****
                  row[icons_clause] = constraint.core.check.getDDL();
              } catch (Exception e) {}
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 2805,2811 ----
                  row[icons_clause] = constraint.core.check.getDDL();
              } catch (Exception e) {}
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
***************
*** 2974,2980 ****
                  }
              }
  
!             t.insert(row);
          }
  
          t.setDataReadOnly(true);
--- 2974,2980 ----
                  }
              }
  
!             t.insertSys(row);
          }
  
          t.setDataReadOnly(true);
*** misc/hsqldb/src/org/hsqldb/DatabaseScript.java	Wed Mar  2 14:50:47 2005
--- misc/build/hsqldb/src/org/hsqldb/DatabaseScript.java	Thu Mar 31 10:35:27 2005
***************
*** 72,77 ****
--- 72,78 ----
  import org.hsqldb.lib.HsqlArrayList;
  import org.hsqldb.lib.IntValueHashMap;
  import org.hsqldb.lib.Iterator;
+ import org.hsqldb.lib.StringConverter;
  
  /**
   * Script generation.
***************
*** 247,252 ****
--- 248,262 ----
              addRow(r, "SET IGNORECASE TRUE");
          }
  
+         // collation for database
+         if (dDatabase.collation.name != null) {
+             String name =
+                 StringConverter.toQuotedString(dDatabase.collation.name, '"',
+                                                true);
+ 
+             addRow(r, "SET DATABASE COLLATION " + name);
+         }
+ 
          // aliases
          HashMap  h       = dDatabase.getAliasMap();
          HashMap  builtin = Library.getAliasMap();
*** misc/hsqldb/src/org/hsqldb/Expression.java	Wed Mar  2 14:50:48 2005
--- misc/build/hsqldb/src/org/hsqldb/Expression.java	Thu Mar 31 10:35:27 2005
***************
*** 69,74 ****
--- 69,75 ----
  import org.hsqldb.lib.HashSet;
  import org.hsqldb.lib.HsqlArrayList;
  import org.hsqldb.store.ValuePool;
+ import org.hsqldb.index.RowIterator;
  
  // fredt@users 20020215 - patch 1.7.0 by fredt
  // to preserve column size etc. when SELECT INTO TABLE is used
***************
*** 101,107 ****
                       VALUELIST = 5,
                       ASTERIX   = 6,
                       FUNCTION  = 7,
!                      LIMIT     = 8;
  
  // boucherb@users 20020410 - parametric compiled statements
      // new leaf type
--- 102,109 ----
                       VALUELIST = 5,
                       ASTERIX   = 6,
                       FUNCTION  = 7,
!                      LIMIT     = 8,
!                      ROW       = 9;
  
  // boucherb@users 20020410 - parametric compiled statements
      // new leaf type
***************
*** 129,135 ****
                       OR            = 29,
                       IN            = 30,
                       EXISTS        = 31,
!                      IS_NULL       = 32;
  
      // aggregate functions
      static final int COUNT       = 40,
--- 131,139 ----
                       OR            = 29,
                       IN            = 30,
                       EXISTS        = 31,
!                      ALL           = 32,
!                      ANY           = 33,
!                      IS_NULL       = 34;
  
      // aggregate functions
      static final int COUNT       = 40,
***************
*** 172,178 ****
                       WHEN         = 110,
                       THEN         = 111,
                       ELSE         = 112,
!                      ENDWHEN      = 113;
  
      // used inside brackets for system functions
      static final int     AS                      = 122,
--- 176,184 ----
                       WHEN         = 110,
                       THEN         = 111,
                       ELSE         = 112,
!                      ENDWHEN      = 113,
!                      DISTINCT     = 114,
!                      VIEW         = 115;
  
      // used inside brackets for system functions
      static final int     AS                      = 122,
***************
*** 228,235 ****
  
      // QUERY - in single value selects, IN or EXISTS predicates
      Select  subSelect;
!     boolean isCorrelated;                     // correlated subquery
!     Table   subTable;                         // if not correlated
  
      // FUNCTION
      Function function;
--- 234,241 ----
  
      // QUERY - in single value selects, IN or EXISTS predicates
      Select  subSelect;
!     boolean isCorrelated;                           // correlated subquery
!     Table   subTable;                               // if not correlated
  
      // FUNCTION
      Function function;
***************
*** 242,261 ****
      private String      schema;
      private String      tableName;
      private String      columnName;
!     private TableFilter tableFilter;          // null if not yet resolved
!     TableFilter         outerFilter;          // defined if this is part of an OUTER JOIN condition tree
  
      //
      private int     columnIndex;
      private boolean columnQuoted;
      private int     precision;
      private int     scale;
!     private String  columnAlias;              // if it is a column of a select column list
      private boolean aliasQuoted;
  
      //
!     private boolean isDescending;             // if it is a column in a order by
!     int             orderColumnIndex = -1;    // >= 0 when it is used for order by
  
  // rougier@users 20020522 - patch 552830 - COUNT(DISTINCT)
      // {COUNT|SUM|MIN|MAX|AVG}(distinct ...)
--- 248,267 ----
      private String      schema;
      private String      tableName;
      private String      columnName;
!     private TableFilter tableFilter;                // null if not yet resolved
!     TableFilter         outerFilter;                // defined if this is part of an OUTER JOIN condition tree
  
      //
      private int     columnIndex;
      private boolean columnQuoted;
      private int     precision;
      private int     scale;
!     private String  columnAlias;                    // if it is a column of a select column list
      private boolean aliasQuoted;
  
      //
!     private boolean isDescending;                   // if it is a column in a order by
!     int             joinedTableColumnIndex = -1;    // >= 0 when it is used for order by
  
  // rougier@users 20020522 - patch 552830 - COUNT(DISTINCT)
      // {COUNT|SUM|MIN|MAX|AVG}(distinct ...)
***************
*** 375,380 ****
--- 381,388 ----
          this.dataType  = dataType;
          this.precision = precision;
          this.scale     = scale;
+ 
+         checkAggregate();
      }
  
      /**
***************
*** 384,395 ****
       * @param e2 operand 2
       * @param escape escape character
       */
!     Expression(Expression e, Expression e2, Character escape) {
  
          exprType   = LIKE;
          eArg       = e;
          eArg2      = e2;
!         likeObject = new Like(escape);
  
          checkAggregate();
      }
--- 392,404 ----
       * @param e2 operand 2
       * @param escape escape character
       */
!     Expression(Expression e, Expression e2, Character escape,
!                boolean hasCollation) {
  
          exprType   = LIKE;
          eArg       = e;
          eArg2      = e2;
!         likeObject = new Like(escape, hasCollation);
  
          checkAggregate();
      }
***************
*** 699,704 ****
--- 708,725 ----
  
                  return buf.toString();
  
+             case ALL :
+                 buf.append(left).append(' ').append(Token.T_ALL).append(
+                     ' ').append(right);
+ 
+                 return buf.toString();
+ 
+             case ANY :
+                 buf.append(left).append(' ').append(Token.T_ANY).append(
+                     ' ').append(right);
+ 
+                 return buf.toString();
+ 
              case IN :
                  buf.append(left).append(' ').append(Token.T_IN).append(
                      ' ').append(right);
***************
*** 942,947 ****
--- 963,976 ----
                  buf.append("OR ");
                  break;
  
+             case ALL :
+                 buf.append("ALL ");
+                 break;
+ 
+             case ANY :
+                 buf.append("ANY ");
+                 break;
+ 
              case IN :
                  buf.append("IN ");
                  break;
***************
*** 1158,1165 ****
       * @return boolean
       */
      boolean canBeInOrderBy() {
!         return exprType == FUNCTION || orderColumnIndex != -1 || isColumn()
!                || isAggregate();
      }
  
      /**
--- 1187,1194 ----
       * @return boolean
       */
      boolean canBeInOrderBy() {
!         return exprType == FUNCTION || joinedTableColumnIndex != -1
!                || isColumn() || isAggregate();
      }
  
      /**
***************
*** 1440,1469 ****
              return columnAlias;
          }
  
-         if (exprType == VALUE) {
-             return "";
-         }
- 
          if (exprType == COLUMN) {
              return columnName;
          }
  
! // fredt@users 20020130 - patch 497872 by Nitin Chauhan - modified
! // return column name for aggregates without alias
!         if (eArg != null) {
!             String name = eArg.getColumnName();
! 
!             if (name.length() > 0) {
!                 return name;
!             }
!         }
! 
!         return eArg2 == null ? ""
!                              : eArg2.getAlias();
      }
  
      /**
!      * Is an column alias quoted
       *
       * @return boolean
       */
--- 1469,1483 ----
              return columnAlias;
          }
  
          if (exprType == COLUMN) {
              return columnName;
          }
  
!         return "";
      }
  
      /**
!      * Is a column alias quoted
       *
       * @return boolean
       */
***************
*** 1565,1571 ****
              if (tableFilter == null) {
  
                  // if an order by column alias
!                 result = orderColumnIndex != -1;
  
                  if (!result && check) {
                      String err = tableName == null ? columnName
--- 1579,1585 ----
              if (tableFilter == null) {
  
                  // if an order by column alias
!                 result = joinedTableColumnIndex != -1;
  
                  if (!result && check) {
                      String err = tableName == null ? columnName
***************
*** 1651,1656 ****
--- 1665,1674 ----
                  }
                  break;
  
+             case ALL :
+             case ANY :
+                 break;
+ 
              case IN :
                  if (eArg2.exprType != QUERY) {
                      Expression[] vl = eArg2.valueList;
***************
*** 1811,1823 ****
                      int   i     = table.searchColumn(columnName);
  
                      if (i != -1) {
- /*
- // fredt@users 20011110 - fix for 471711 - subselects
-                         boolean repeat = tableFilter != null && !tableFilter.getName().equals(filterName);
-                         if ( repeat){
-                              throw Trace.error(Trace.AMBIGUOUS_COLUMN_REFERENCE, columnName);
-                         }
- */
                          tableFilter = f;
                          columnIndex = i;
                          tableName   = filterName;
--- 1829,1834 ----
***************
*** 1845,1850 ****
--- 1856,1865 ----
                  }
                  break;
  
+             case ALL :
+             case ANY :
+                 break;
+ 
              case IN :
                  if (eArg2.exprType != QUERY) {
                      Expression[] vl = eArg2.valueList;
***************
*** 1859,1888 ****
          }
      }
  
!     void resolveTypes() throws HsqlException {
  
          if (isParam || exprType == Expression.VALUE) {
              return;
          }
  
          if (eArg != null) {
!             eArg.resolveTypes();
          }
  
          if (eArg2 != null) {
!             eArg2.resolveTypes();
          }
  
          switch (exprType) {
  
              case FUNCTION :
!                 function.resolveType();
  
                  dataType = function.getReturnType();
                  break;
  
              case QUERY : {
!                 subSelect.resolveTypes();
  
                  dataType = subSelect.exprColumns[0].dataType;
  
--- 1874,1910 ----
          }
      }
  
!     void resolveTypes(Database database) throws HsqlException {
! 
!         Session session;
  
          if (isParam || exprType == Expression.VALUE) {
              return;
          }
  
          if (eArg != null) {
!             eArg.resolveTypes(database);
          }
  
          if (eArg2 != null) {
!             eArg2.resolveTypes(database);
          }
  
+         session = database.sessionManager.getSysSession();
+ 
          switch (exprType) {
  
+             case COLUMN :
+                 break;
+ 
              case FUNCTION :
!                 function.resolveType(database);
  
                  dataType = function.getReturnType();
                  break;
  
              case QUERY : {
!                 subSelect.resolveTypes(database);
  
                  dataType = subSelect.exprColumns[0].dataType;
  
***************
*** 1897,1903 ****
                  dataType = eArg.dataType;
  
                  if (isFixedConstant()) {
!                     valueData = getValue(null, dataType);
                      eArg      = null;
                      exprType  = VALUE;
                  }
--- 1919,1925 ----
                  dataType = eArg.dataType;
  
                  if (isFixedConstant()) {
!                     valueData = getValue(session, dataType);
                      eArg      = null;
                      exprType  = VALUE;
                  }
***************
*** 1913,1919 ****
                      dataType = Types.VARCHAR;
  
                      if (isFixedConstant()) {
!                         valueData = getValue(null, dataType);
                          eArg      = null;
                          eArg2     = null;
                          exprType  = VALUE;
--- 1935,1941 ----
                      dataType = Types.VARCHAR;
  
                      if (isFixedConstant()) {
!                         valueData = getValue(session, dataType);
                          eArg      = null;
                          eArg2     = null;
                          exprType  = VALUE;
***************
*** 1940,1946 ****
                  if (isFixedConstant()) {
                      dataType = Column.getCombinedNumberType(eArg.dataType,
                              eArg2.dataType, exprType);
!                     valueData = getValue(null, dataType);
                      eArg      = null;
                      eArg2     = null;
                      exprType  = VALUE;
--- 1962,1968 ----
                  if (isFixedConstant()) {
                      dataType = Column.getCombinedNumberType(eArg.dataType,
                              eArg2.dataType, exprType);
!                     valueData = getValue(session, dataType);
                      eArg      = null;
                      eArg2     = null;
                      exprType  = VALUE;
***************
*** 1961,1967 ****
                  dataType = Types.VARCHAR;
  
                  if (isFixedConstant()) {
!                     valueData = getValue(null, dataType);
                      eArg      = null;
                      eArg2     = null;
                      exprType  = VALUE;
--- 1983,1989 ----
                  dataType = Types.VARCHAR;
  
                  if (isFixedConstant()) {
!                     valueData = getValue(session, dataType);
                      eArg      = null;
                      eArg2     = null;
                      exprType  = VALUE;
***************
*** 1988,1994 ****
                  }
  
                  if (isFixedConditional()) {
!                     Boolean result = test(null);
  
                      if (result == null) {
                          setNull();
--- 2010,2016 ----
                  }
  
                  if (isFixedConditional()) {
!                     Boolean result = test(session);
  
                      if (result == null) {
                          setNull();
***************
*** 2022,2028 ****
                  break;
  
              case LIKE :
!                 resolveTypeForLike();
  
                  dataType = Types.BOOLEAN;
                  break;
--- 2044,2050 ----
                  break;
  
              case LIKE :
!                 resolveTypeForLike(database);
  
                  dataType = Types.BOOLEAN;
                  break;
***************
*** 2030,2038 ****
              case AND : {
                  boolean argFixed  = eArg.isFixedConditional();
                  boolean arg2Fixed = eArg2.isFixedConditional();
!                 Boolean arg       = argFixed ? (eArg.test(null))
                                               : null;
!                 Boolean arg2      = arg2Fixed ? eArg2.test(null)
                                                : null;
  
                  if (argFixed && arg2Fixed) {
--- 2052,2060 ----
              case AND : {
                  boolean argFixed  = eArg.isFixedConditional();
                  boolean arg2Fixed = eArg2.isFixedConditional();
!                 Boolean arg       = argFixed ? (eArg.test(session))
                                               : null;
!                 Boolean arg2      = arg2Fixed ? eArg2.test(session)
                                                : null;
  
                  if (argFixed && arg2Fixed) {
***************
*** 2067,2075 ****
              case OR : {
                  boolean argFixed  = eArg.isFixedConditional();
                  boolean arg2Fixed = eArg2.isFixedConditional();
!                 Boolean arg       = argFixed ? (eArg.test(null))
                                               : null;
!                 Boolean arg2      = arg2Fixed ? eArg2.test(null)
                                                : null;
  
                  if (argFixed && arg2Fixed) {
--- 2089,2097 ----
              case OR : {
                  boolean argFixed  = eArg.isFixedConditional();
                  boolean arg2Fixed = eArg2.isFixedConditional();
!                 Boolean arg       = argFixed ? (eArg.test(session))
                                               : null;
!                 Boolean arg2      = arg2Fixed ? eArg2.test(session)
                                                : null;
  
                  if (argFixed && arg2Fixed) {
***************
*** 2103,2110 ****
              }
              case IS_NULL :
                  if (isFixedConditional()) {
!                     exprType = Boolean.TRUE.equals(test(null)) ? TRUE
!                                                                : FALSE;
                      eArg     = null;
                  }
  
--- 2125,2132 ----
              }
              case IS_NULL :
                  if (isFixedConditional()) {
!                     exprType = Boolean.TRUE.equals(test(session)) ? TRUE
!                                                                   : FALSE;
                      eArg     = null;
                  }
  
***************
*** 2113,2119 ****
  
              case NOT :
                  if (isFixedConditional()) {
!                     Boolean arg = test(null);
  
                      if (arg == null) {
                          setNull();
--- 2135,2141 ----
  
              case NOT :
                  if (isFixedConditional()) {
!                     Boolean arg = test(session);
  
                      if (arg == null) {
                          setNull();
***************
*** 2129,2136 ****
                  dataType = Types.BOOLEAN;
                  break;
  
              case IN :
!                 resolveTypeForIn();
  
                  dataType = Types.BOOLEAN;
                  break;
--- 2151,2163 ----
                  dataType = Types.BOOLEAN;
                  break;
  
+             case ALL :
+             case ANY :
+                 dataType = eArg.dataType;
+                 break;
+ 
              case IN :
!                 resolveTypeForIn(database);
  
                  dataType = Types.BOOLEAN;
                  break;
***************
*** 2175,2181 ****
                  // NOTE: both iDataType for this expr and for eArg (if isParm)
                  // are already set in Parser during read
                  if (eArg.isFixedConstant() || eArg.isFixedConditional()) {
!                     valueData = getValue(null);
                      exprType  = VALUE;
                      eArg      = null;
                  }
--- 2202,2208 ----
                  // NOTE: both iDataType for this expr and for eArg (if isParm)
                  // are already set in Parser during read
                  if (eArg.isFixedConstant() || eArg.isFixedConditional()) {
!                     valueData = getValue(session);
                      exprType  = VALUE;
                      eArg      = null;
                  }
***************
*** 2253,2267 ****
          }
      }
  
!     void resolveTypeForLike() throws HsqlException {
  
          if (eArg.isParam && eArg2.isParam) {
              throw Trace.error(Trace.UNRESOLVED_PARAMETER_TYPE,
                                Trace.Expression_resolveTypeForLike);
          }
  
          if (isFixedConditional()) {
!             Boolean arg = test(null);
  
              if (arg == null) {
                  setNull();
--- 2280,2296 ----
          }
      }
  
!     void resolveTypeForLike(Database database) throws HsqlException {
  
          if (eArg.isParam && eArg2.isParam) {
              throw Trace.error(Trace.UNRESOLVED_PARAMETER_TYPE,
                                Trace.Expression_resolveTypeForLike);
          }
  
+         Session session = database.sessionManager.getSysSession();
+ 
          if (isFixedConditional()) {
!             Boolean arg = test(session);
  
              if (arg == null) {
                  setNull();
***************
*** 2302,2308 ****
  
          boolean isRightArgFixedConstant = eArg2.isFixedConstant();
          String likeStr = isRightArgFixedConstant
!                          ? (String) eArg2.getValue(null, Types.VARCHAR)
                           : null;
          boolean ignoreCase = eArg.dataType == Types.VARCHAR_IGNORECASE
                               || eArg2.dataType == Types.VARCHAR_IGNORECASE;
--- 2331,2337 ----
  
          boolean isRightArgFixedConstant = eArg2.isFixedConstant();
          String likeStr = isRightArgFixedConstant
!                          ? (String) eArg2.getValue(session, Types.VARCHAR)
                           : null;
          boolean ignoreCase = eArg.dataType == Types.VARCHAR_IGNORECASE
                               || eArg2.dataType == Types.VARCHAR_IGNORECASE;
***************
*** 2327,2340 ****
              exprType   = EQUAL;
              eArg2 = new Expression(Types.VARCHAR, likeObject.getRangeLow());
              likeObject = null;
!         } else if (likeObject.isEquivalentToNotNullPredicate()) {
! 
!             // X LIKE '%' <=>  X IS NOT NULL
!             exprType   = NOT;
!             eArg       = new Expression(IS_NULL, eArg, null);
!             eArg2      = null;
!             likeObject = null;
!         } else {
              if (eArg.exprType != Expression.COLUMN) {
  
                  // Then we are done here, since range predicates are
--- 2356,2363 ----
              exprType   = EQUAL;
              eArg2 = new Expression(Types.VARCHAR, likeObject.getRangeLow());
              likeObject = null;
!         } else if (likeObject.isEquivalentToNotNullPredicate()) {}
!         else {
              if (eArg.exprType != Expression.COLUMN) {
  
                  // Then we are done here, since range predicates are
***************
*** 2368,2381 ****
              if (likeObject.isEquivalentToBetweenPredicate()) {
  
                  // X LIKE 'abc%' <=> X >= 'abc' AND X <= 'abc' || max_collation_char
!                 larger  = Column.sql_compare_in_locale;
                  between = !larger;
                  like    = larger;
              } else if (likeObject
                      .isEquivalentToBetweenPredicateAugmentedWithLike()) {
  
                  // X LIKE 'abc%...' <=> X >= 'abc' AND X <= 'abc' || max_collation_char AND X LIKE 'abc%...'
!                 larger  = Column.sql_compare_in_locale;
                  between = !larger;
                  like    = true;
              }
--- 2391,2404 ----
              if (likeObject.isEquivalentToBetweenPredicate()) {
  
                  // X LIKE 'abc%' <=> X >= 'abc' AND X <= 'abc' || max_collation_char
!                 larger  = likeObject.hasCollation;
                  between = !larger;
                  like    = larger;
              } else if (likeObject
                      .isEquivalentToBetweenPredicateAugmentedWithLike()) {
  
                  // X LIKE 'abc%...' <=> X >= 'abc' AND X <= 'abc' || max_collation_char AND X LIKE 'abc%...'
!                 larger  = likeObject.hasCollation;
                  between = !larger;
                  like    = true;
              }
***************
*** 2400,2406 ****
                  Expression gte = new Expression(BIGGER_EQUAL, eArg, eFirst);
                  Expression lte = new Expression(SMALLER_EQUAL, eArg, eLast);
  
!                 eArg2 = new Expression(eArg, eArg2, likeObject.escapeChar);
                  eArg2.likeObject = likeObject;
                  eArg             = new Expression(AND, gte, lte);
                  exprType         = AND;
--- 2423,2430 ----
                  Expression gte = new Expression(BIGGER_EQUAL, eArg, eFirst);
                  Expression lte = new Expression(SMALLER_EQUAL, eArg, eLast);
  
!                 eArg2 = new Expression(eArg, eArg2, likeObject.escapeChar,
!                                        likeObject.hasCollation);
                  eArg2.likeObject = likeObject;
                  eArg             = new Expression(AND, gte, lte);
                  exprType         = AND;
***************
*** 2408,2414 ****
              } else if (larger) {
                  Expression gte = new Expression(BIGGER_EQUAL, eArg, eFirst);
  
!                 eArg2 = new Expression(eArg, eArg2, likeObject.escapeChar);
                  eArg2.likeObject = likeObject;
                  eArg             = gte;
                  exprType         = AND;
--- 2432,2439 ----
              } else if (larger) {
                  Expression gte = new Expression(BIGGER_EQUAL, eArg, eFirst);
  
!                 eArg2 = new Expression(eArg, eArg2, likeObject.escapeChar,
!                                        likeObject.hasCollation);
                  eArg2.likeObject = likeObject;
                  eArg             = gte;
                  exprType         = AND;
***************
*** 2430,2441 ****
  //                             to be a parameter marker if the list is empty.
  // CHECKME:
  // Is an empty IN list legal?  Why would anyone ever use it?
!     void resolveTypeForIn() throws HsqlException {
  
          if (eArg2.exprType == QUERY) {
              if (eArg.isParam) {
                  eArg.dataType = eArg2.dataType;
              }
          } else {    // eArg2.exprType == VALUELIST
              Expression[] vl  = eArg2.valueList;
              int          len = vl.length;
--- 2455,2470 ----
  //                             to be a parameter marker if the list is empty.
  // CHECKME:
  // Is an empty IN list legal?  Why would anyone ever use it?
!     void resolveTypeForIn(Database database) throws HsqlException {
! 
!         Session session = database.sessionManager.getSysSession();
  
          if (eArg2.exprType == QUERY) {
              if (eArg.isParam) {
                  eArg.dataType = eArg2.dataType;
              }
+ 
+             isCorrelated = eArg2.isCorrelated;
          } else {    // eArg2.exprType == VALUELIST
              Expression[] vl  = eArg2.valueList;
              int          len = vl.length;
***************
*** 2477,2483 ****
                              e.dataType = dt;
                          }
                      } else {
!                         e.resolveTypes();
                      }
                  }
              } else {
--- 2506,2512 ----
                              e.dataType = dt;
                          }
                      } else {
!                         e.resolveTypes(database);
                      }
                  }
              } else {
***************
*** 2495,2501 ****
                              e.dataType = dt;
                          }
                      } else {
!                         e.resolveTypes();
                      }
                  }
              }
--- 2524,2530 ----
                              e.dataType = dt;
                          }
                      } else {
!                         e.resolveTypes(database);
                      }
                  }
              }
***************
*** 2505,2510 ****
--- 2534,2540 ----
              for (int i = 0; i < len; i++) {
                  if (!vl[i].isFixedConstant()) {
                      eArg2.isFixedConstantValueList = false;
+                     isCorrelated                   = true;
  
                      break;
                  }
***************
*** 2515,2521 ****
  
                  for (int i = 0; i < len; i++) {
                      try {
!                         Object value = eArg2.valueList[i].getValue(null);
  
                          value = Column.convertObject(value, eArg2.dataType);
  
--- 2545,2551 ----
  
                  for (int i = 0; i < len; i++) {
                      try {
!                         Object value = eArg2.valueList[i].getValue(session);
  
                          value = Column.convertObject(value, eArg2.dataType);
  
***************
*** 2598,2603 ****
--- 2628,2647 ----
      }
  
      /**
+      * Returns the table name for a column expression as a string
+      *
+      * @return table name
+      */
+     String getFilterTableName() {
+ 
+         if (tableFilter == null) {
+             return "";
+         } else {
+             return tableFilter.getTable().getName().name;
+         }
+     }
+ 
+     /**
       * Returns the name of a column as string
       *
       * @return column name
***************
*** 2732,2745 ****
          return Column.convertObject(o, type);
      }
  
- /** @todo fredt - should be rewritten to handle only set function operation,
-      *  with other operations handled in the normal way */
-     Object getAggregatedValue(Session session, Object currValue,
-                               int type) throws HsqlException {
-         return Column.convertObject(getAggregatedValue(session, currValue),
-                                     type);
-     }
- 
      /**
       * Get the result of a SetFunction or an ordinary value
       *
--- 2776,2781 ----
***************
*** 2788,2795 ****
  
              case CONVERT :
                  return Column.convertObject(
!                     eArg.getAggregatedValue(session, currValue), dataType,
!                     precision, scale);
          }
  
          // handle expressions
--- 2824,2831 ----
  
              case CONVERT :
                  return Column.convertObject(
!                     session, eArg.getAggregatedValue(session, currValue),
!                     dataType, precision, scale);
          }
  
          // handle expressions
***************
*** 2799,2813 ****
          switch (aggregateSpec) {
  
              case AGGREGATE_LEFT :
!                 leftValue  = eArg.getAggregatedValue(session, currValue);
!                 rightValue = eArg2 == null ? null
!                                            : eArg2.getValue(session);
                  break;
  
              case AGGREGATE_RIGHT :
!                 leftValue  = eArg == null ? null
!                                           : eArg.getValue(session);
!                 rightValue = eArg2.getAggregatedValue(session, currValue);
                  break;
  
              case AGGREGATE_BOTH :
--- 2835,2859 ----
          switch (aggregateSpec) {
  
              case AGGREGATE_LEFT :
!                 if (currValue == null) {
!                     currValue = new Object[2];
!                 }
! 
!                 leftValue =
!                     eArg.getAggregatedValue(session,
!                                             ((Object[]) currValue)[0]);
!                 rightValue = ((Object[]) currValue)[1];
                  break;
  
              case AGGREGATE_RIGHT :
!                 if (currValue == null) {
!                     currValue = new Object[2];
!                 }
! 
!                 leftValue = ((Object[]) currValue)[0];
!                 rightValue =
!                     eArg2.getAggregatedValue(session,
!                                              ((Object[]) currValue)[1]);
                  break;
  
              case AGGREGATE_BOTH :
***************
*** 2827,2833 ****
          // handle other operations
          switch (exprType) {
  
- // tony_lai@users having >>>
              case TRUE :
                  return Boolean.TRUE;
  
--- 2873,2878 ----
***************
*** 2835,2857 ****
                  return Boolean.FALSE;
  
              case NOT :
!                 Trace.doAssert(eArg2 == null,
!                                "Expression.getAggregatedValue.NOT");
  
                  return ((Boolean) leftValue).booleanValue() ? Boolean.FALSE
                                                              : Boolean.TRUE;
  
              case AND :
                  return ((Boolean) leftValue).booleanValue()
                         && ((Boolean) rightValue).booleanValue() ? Boolean.TRUE
                                                                  : Boolean
                                                                  .FALSE;
  
              case OR :
!                 return ((Boolean) leftValue).booleanValue()
!                        || ((Boolean) rightValue).booleanValue() ? Boolean.TRUE
!                                                                 : Boolean
!                                                                 .FALSE;
  
              case IS_NULL :
                  return leftValue == null ? Boolean.TRUE
--- 2880,2909 ----
                  return Boolean.FALSE;
  
              case NOT :
!                 if (leftValue == null) {
!                     return null;
!                 }
  
                  return ((Boolean) leftValue).booleanValue() ? Boolean.FALSE
                                                              : Boolean.TRUE;
  
              case AND :
+                 if (leftValue == null || rightValue == null) {
+                     return null;
+                 }
+ 
                  return ((Boolean) leftValue).booleanValue()
                         && ((Boolean) rightValue).booleanValue() ? Boolean.TRUE
                                                                  : Boolean
                                                                  .FALSE;
  
              case OR :
!                 if (Boolean.TRUE.equals(leftValue)) {
!                     return Boolean.TRUE;
!                 }
! 
!                 return Boolean.TRUE.equals(rightValue) ? Boolean.TRUE
!                                                        : Boolean.FALSE;
  
              case IS_NULL :
                  return leftValue == null ? Boolean.TRUE
***************
*** 2868,2875 ****
                  String c = (String) Column.convertObject(leftValue,
                      Types.VARCHAR);
  
!                 return likeObject.compare(c) ? Boolean.TRUE
!                                              : Boolean.FALSE;
  
              case IN :
                  return eArg2.testValueList(session, leftValue);
--- 2920,2929 ----
                  String c = (String) Column.convertObject(leftValue,
                      Types.VARCHAR);
  
!                 return likeObject.compare(session, c);
! 
!             case ALL :
!                 return eArg.getSingleValueFromQurey(session);
  
              case IN :
                  return eArg2.testValueList(session, leftValue);
***************
*** 2935,2941 ****
              int valueType = eArg.isColumn() ? eArg.dataType
                                              : eArg2.dataType;
  
!             return compareValues(leftValue, rightValue, valueType, exprType)
                     ? Boolean.TRUE
                     : Boolean.FALSE;
          }
--- 2989,2995 ----
              int valueType = eArg.isColumn() ? eArg.dataType
                                              : eArg2.dataType;
  
!             return compareValues(session, leftValue, rightValue, valueType, exprType)
                     ? Boolean.TRUE
                     : Boolean.FALSE;
          }
***************
*** 2999,3005 ****
                                                             : eArg.getValue(
                                                                 session);
  
!                 ((SetFunction) currValue).add(newValue);
  
                  return currValue;
              }
--- 3053,3059 ----
                                                             : eArg.getValue(
                                                                 session);
  
!                 ((SetFunction) currValue).add(session, newValue);
  
                  return currValue;
              }
***************
*** 3017,3028 ****
  
                  return valuePair;
              }
!             case AGGREGATE_LEFT :
!                 return eArg.updateAggregatingValue(session, currValue);
  
!             case AGGREGATE_RIGHT :
!                 return eArg2.updateAggregatingValue(session, currValue);
  
              case AGGREGATE_FUNCTION :
                  return function.updateAggregatingValue(session, currValue);
  
--- 3071,3108 ----
  
                  return valuePair;
              }
!             case AGGREGATE_LEFT : {
!                 Object[] valuePair = (Object[]) currValue;
  
!                 if (valuePair == null) {
!                     valuePair = new Object[2];
!                 }
! 
!                 valuePair[0] = eArg.updateAggregatingValue(session,
!                         valuePair[0]);
! 
!                 if (eArg2 != null) {
!                     valuePair[1] = eArg2.getValue(session);
!                 }
! 
!                 return valuePair;
!             }
!             case AGGREGATE_RIGHT : {
!                 Object[] valuePair = (Object[]) currValue;
  
+                 if (valuePair == null) {
+                     valuePair = new Object[2];
+                 }
+ 
+                 if (eArg != null) {
+                     valuePair[0] = eArg.getValue(session);
+                 }
+ 
+                 valuePair[1] = eArg2.updateAggregatingValue(session,
+                         valuePair[1]);
+ 
+                 return valuePair;
+             }
              case AGGREGATE_FUNCTION :
                  return function.updateAggregatingValue(session, currValue);
  
***************
*** 3056,3061 ****
--- 3136,3144 ----
                  return Column.negate(eArg.getValue(session, dataType),
                                       dataType);
  
+             case ALL :
+                 return eArg.getSingleValueFromQurey(session);
+ 
              case AND :
              case OR :
              case LIKE :
***************
*** 3064,3071 ****
                  return test(session);
  
              case CONVERT :
!                 return Column.convertObject(eArg.getValue(session), dataType,
!                                             precision, scale);
  
              case CASEWHEN :
                  Boolean result = eArg.test(session);
--- 3147,3154 ----
                  return test(session);
  
              case CONVERT :
!                 return Column.convertObject(session, eArg.getValue(session),
!                                             dataType, precision, scale);
  
              case CASEWHEN :
                  Boolean result = eArg.test(session);
***************
*** 3154,3161 ****
                                                                : Boolean.TRUE;
  
              case AND : {
- 
-                 // can't use C style optimization because of NULL
                  Boolean r1 = eArg.test(session);
  
                  if (r1 == null) {
--- 3237,3242 ----
***************
*** 3195,3202 ****
  
                  String c = (String) eArg.getValue(session, Types.VARCHAR);
  
!                 return likeObject.compare(c) ? Boolean.TRUE
!                                              : Boolean.FALSE;
  
              case IN :
                  return eArg2.testValueList(session, eArg.getValue(session));
--- 3276,3282 ----
  
                  String c = (String) eArg.getValue(session, Types.VARCHAR);
  
!                 return likeObject.compare(session, c);
  
              case IN :
                  return eArg2.testValueList(session, eArg.getValue(session));
***************
*** 3255,3268 ****
              return null;
          }
  
!         return compareValues(o, o2, type, exprType) ? Boolean.TRUE
!                                                     : Boolean.FALSE;
      }
  
!     private static boolean compareValues(Object o, Object o2, int valueType,
                                           int exprType) throws HsqlException {
  
!         int result = Column.compare(o, o2, valueType);
  
          switch (exprType) {
  
--- 3335,3350 ----
              return null;
          }
  
!         return compareValues(session, o, o2, type, exprType) ? Boolean.TRUE
!                                                              : Boolean.FALSE;
      }
  
!     private static boolean compareValues(Session session, Object o,
!                                          Object o2, int valueType,
                                           int exprType) throws HsqlException {
  
!         int result = Column.compare(session.database.collation, o, o2,
!                                     valueType);
  
          switch (exprType) {
  
***************
*** 3327,3333 ****
              for (int i = 0; i < len; i++) {
                  Object o2 = valueList[i].getValue(session, dataType);
  
!                 if (Column.compare(o, o2, dataType) == 0) {
                      return Boolean.TRUE;
                  }
              }
--- 3409,3416 ----
              for (int i = 0; i < len; i++) {
                  Object o2 = valueList[i].getValue(session, dataType);
  
!                 if (Column.compare(
!                         session.database.collation, o, o2, dataType) == 0) {
                      return Boolean.TRUE;
                  }
              }
***************
*** 3351,3357 ****
              Result r = subSelect.getResult(session, 0);
  
              // fredt - reduce the size if possible
!             r.removeDuplicates();
  
              Record n    = r.rRoot;
              int    type = r.metaData.colTypes[0];
--- 3434,3440 ----
              Result r = subSelect.getResult(session, 0);
  
              // fredt - reduce the size if possible
!             r.removeDuplicates(session);
  
              Record n    = r.rRoot;
              int    type = r.metaData.colTypes[0];
***************
*** 3365,3371 ****
              while (n != null) {
                  Object o2 = n.data[0];
  
!                 if (o2 != null && Column.compare(o2, o, type) == 0) {
                      return Boolean.TRUE;
                  }
  
--- 3448,3456 ----
              while (n != null) {
                  Object o2 = n.data[0];
  
!                 if (o2 != null
!                         && Column.compare(
!                             session.database.collation, o2, o, type) == 0) {
                      return Boolean.TRUE;
                  }
  
***************
*** 3379,3384 ****
--- 3464,3542 ----
      }
  
      /**
+      *
+      */
+     private Object getSingleValueFromQurey(Session session)
+     throws HsqlException {
+ 
+         if (exprType == QUERY) {
+             if (subTable != null) {
+                 RowIterator it = subTable.getPrimaryIndex().firstRow(session);
+                 Row         row = it.next();
+ 
+                 if (row == null) {
+                     return null;
+                 }
+ 
+                 Object value = row.getData()[0];
+ 
+                 row = it.next();
+ 
+                 return row == null ? value
+                                    : null;
+             }
+ 
+             Result r = subSelect.getResult(session, 0);
+ 
+             r.removeDuplicates(session);
+ 
+             if (r.getSize() == 1) {
+                 Record n = r.rRoot;
+ 
+                 return n.data[0];
+             }
+ 
+             return null;
+         }
+ 
+         throw Trace.error(Trace.WRONG_DATA_TYPE);
+     }
+ 
+     /**
+      * For ANY expressions. Todo
+      */
+     private boolean compareValues(Session session, Object o,
+                                   int exprType) throws HsqlException {
+ 
+         int result = 0;
+ 
+         switch (exprType) {
+ 
+             case EQUAL :
+                 return result == 0;
+ 
+             case BIGGER :
+                 return result > 0;
+ 
+             case BIGGER_EQUAL :
+                 return result >= 0;
+ 
+             case SMALLER_EQUAL :
+                 return result <= 0;
+ 
+             case SMALLER :
+                 return result < 0;
+ 
+             case NOT_EQUAL :
+                 return result != 0;
+ 
+             default :
+                 throw Trace.error(Trace.GENERAL_ERROR,
+                                   Trace.Expression_compareValues);
+         }
+     }
+ 
+     /**
       * Marks all the expressions in the tree for a condition that is part
       * of a JOIN .. ON ....<br>
       *
***************
*** 3449,3455 ****
  
          s.queryCondition = condition;
  
!         s.resolveAll(true);
  
          return s;
      }
--- 3607,3613 ----
  
          s.queryCondition = condition;
  
!         s.resolveAll(t.database, true);
  
          return s;
      }
*** misc/hsqldb/src/org/hsqldb/Function.java	Wed Mar  2 14:50:48 2005
--- misc/build/hsqldb/src/org/hsqldb/Function.java	Thu Mar 31 10:35:27 2005
***************
*** 432,442 ****
              Expression e = eArg[i];
  
              if (eArg[i] != null) {
!                 valueArray[i] = eArg[i].isAggregate()
!                                 ? e.getAggregatedValue(session,
!                                                        valueArray[i],
!                                                        iArgType[i])
!                                 : e.getValue(session, iArgType[i]);
              }
          }
  
--- 432,444 ----
              Expression e = eArg[i];
  
              if (eArg[i] != null) {
!                 if (eArg[i].isAggregate()) {
!                     valueArray[i] = Column.convertObject(
!                         e.getAggregatedValue(session, valueArray[i]),
!                         iArgType[i]);
!                 } else {
!                     valueArray[i] = e.getValue(session, iArgType[i]);
!                 }
              }
          }
  
***************
*** 543,549 ****
       * Resolves the type of this expression and performs certain
       * transformations and optimisations of the expression tree.
       */
!     void resolveType() throws HsqlException {
  
          Expression e;
  
--- 545,551 ----
       * Resolves the type of this expression and performs certain
       * transformations and optimisations of the expression tree.
       */
!     void resolveType(Database database) throws HsqlException {
  
          Expression e;
  
***************
*** 557,563 ****
                      e.nullability    = getArgNullability(i);
                      e.valueClassName = getArgClass(i).getName();
                  } else {
!                     e.resolveTypes();
                  }
              }
          }
--- 559,565 ----
                      e.nullability    = getArgNullability(i);
                      e.valueClassName = getArgClass(i).getName();
                  } else {
!                     e.resolveTypes(database);
                  }
              }
          }
*** misc/hsqldb/src/org/hsqldb/HSQLClientConnection.java	Wed Mar  2 14:50:48 2005
--- misc/build/hsqldb/src/org/hsqldb/HSQLClientConnection.java	Thu Mar 31 10:35:27 2005
***************
*** 62,68 ****
      protected RowOutputBinary rowOut;
      protected RowInputBinary  rowIn;
      private Result            resultOut;
!     private final int         sessionID;
  
  //
      String  host;
--- 62,68 ----
      protected RowOutputBinary rowOut;
      protected RowInputBinary  rowIn;
      private Result            resultOut;
!     private int               sessionID;
  
  //
      String  host;
***************
*** 112,129 ****
  
          rowOut    = new RowOutputBinary(mainBuffer);
          rowIn     = new RowInputBinary(rowOut);
!         resultOut = new Result(ResultConstants.DATA, 7);
!         resultOut.metaData.colNames = resultOut.metaData.colLabels =
!             resultOut.metaData.tableNames = new String[] {
!             "", "", "", "", "", "", ""
!         };
  
          resultOut.add(new Object[7]);
- 
-         resultOut.metaData.colTypes = new int[] {
-             Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.INTEGER,
-             Types.BOOLEAN, Types.BOOLEAN, Types.BOOLEAN
-         };
      }
  
      protected void initConnection(String host, int port,
--- 112,120 ----
  
          rowOut    = new RowOutputBinary(mainBuffer);
          rowIn     = new RowInputBinary(rowOut);
!         resultOut = Result.newSessionAttributesResult();
  
          resultOut.add(new Object[7]);
      }
  
      protected void initConnection(String host, int port,
***************
*** 241,246 ****
--- 232,246 ----
                            : Boolean.FALSE, Session.INFO_AUTOCOMMIT);
      }
  
+     public void setIsolation(int level) throws HsqlException {}
+ 
+     public int getIsolation() throws HsqlException {
+ 
+         Object info = getAttribute(Session.INFO_ISOLATION);
+ 
+         return ((Integer) info).intValue();
+     }
+ 
      public boolean isClosed() {
          return isClosed;
      }
***************
*** 273,278 ****
--- 273,304 ----
          return sessionID;
      }
  
+     /**
+      * Used by pooled connections to reset the server-side session to a new
+      * one. In case of failure, the connection is closed.
+      *
+      * When the Connection.close() method is called, a pooled connection calls
+      * this method instead of HSQLClientConnection.close(). It can then
+      * reuse the HSQLClientConnection object with no further initialisation.
+      *
+      */
+     public void resetSession() throws HsqlException {
+ 
+         Result login    = new Result(ResultConstants.HSQLRESETSESSION);
+         Result resultIn = execute(login);
+ 
+         if (resultIn.mode == ResultConstants.ERROR) {
+             isClosed = true;
+ 
+             closeConnection();
+ 
+             throw Trace.error(resultIn);
+         }
+ 
+         sessionID  = resultIn.sessionID;
+         databaseID = resultIn.databaseID;
+     }
+ 
      protected void write(Result r) throws IOException, HsqlException {
          Result.write(r, rowOut, dataOutput);
      }
*** misc/hsqldb/src/org/hsqldb/HsqlDateTime.java	Wed Mar  2 14:50:48 2005
--- misc/build/hsqldb/src/org/hsqldb/HsqlDateTime.java	Thu Mar 31 10:35:27 2005
***************
*** 285,292 ****
      /**
       * Creates a full length timestamp string, with 9 digist for nanos
       */
!     public static String getTimestampString(Timestamp x,
!             Calendar cal) throws Exception {
  
          synchronized (sdfts) {
              sdfts.setCalendar(cal == null ? tempCalDefault
--- 285,291 ----
      /**
       * Creates a full length timestamp string, with 9 digist for nanos
       */
!     public static String getTimestampString(Timestamp x, Calendar cal) {
  
          synchronized (sdfts) {
              sdfts.setCalendar(cal == null ? tempCalDefault
***************
*** 526,529 ****
--- 525,726 ----
              return tempCalDefault.get(part);
          }
      }
+ 
+     private final static char[][] dateTokens     = {
+         {
+             'R', 'R', 'R', 'R'
+         }, {
+             'I', 'Y', 'Y', 'Y'
+         }, {
+             'Y', 'Y', 'Y', 'Y'
+         }, {
+             'I', 'Y'
+         }, {
+             'Y', 'Y'
+         }, {
+             'B', 'C'
+         }, {
+             'B', '.', 'C', '.'
+         }, {
+             'A', 'D'
+         }, {
+             'A', '.', 'D', '.'
+         }, {
+             'M', 'O', 'N'
+         }, {
+             'M', 'O', 'N', 'T', 'H'
+         }, { 'D' }, {
+             'I', 'W'
+         }, {
+             'D', 'D'
+         }, {
+             'D', 'D', 'D'
+         }, {
+             'H', 'H', '2', '4'
+         }, {
+             'H', 'H', '1', '2'
+         }, {
+             'H', 'H'
+         }, {
+             'M', 'I',
+         }, {
+             'S', 'S'
+         }, {
+             'A', 'M'
+         }, {
+             'P', 'M',
+         }, {
+             'A', '.', 'M', '.'
+         }, {
+             'P', '.', 'M', '.'
+         }
+     };
+     private final static String[] javaDateTokens = {
+         "yyyy", "yyyy", "yyyy", "yy", "yy", "G", "G", "G", "G", "MMM",
+         "MMMMM", "E", "w", "dd", "D", "k", "K", "K", "mm", "ss", "aaa", "aaa",
+         "aaa", "aaa"
+     };
+ 
+     /** Indicates end-of-input */
+     public static final char e = 0xffff;
+ 
+     /**
+      * Converts the given format into a pattern accepted by <code>java.text.SimpleDataFormat</code>
+      * @param format
+      * @return
+      */
+     public static String toJavaDatePattern(String format) {
+ 
+         int          len = format.length();
+         char         ch;
+         StringBuffer pattern   = new StringBuffer(len);
+         Tokenizer    tokenizer = new Tokenizer();
+ 
+         for (int i = 0; i <= len; i++) {
+             ch = (i == len) ? e
+                             : format.charAt(i);
+ 
+             if (!tokenizer.next(ch, dateTokens)) {
+                 int index = tokenizer.getLastMatch();
+ 
+                 if (index >= 0) {
+                     pattern.setLength(pattern.length() - tokenizer.length());
+                     pattern.append(javaDateTokens[index]);
+                 }
+ 
+                 tokenizer.reset();
+ 
+                 if (tokenizer.isConsumed()) {
+                     continue;
+                 }
+             }
+ 
+             pattern.append(ch);
+         }
+ 
+         return pattern.substring(0, pattern.length() - 1);
+     }
+ 
+     /**
+      * This class can match 64 tokens at maximum.
+      */
+     static class Tokenizer {
+ 
+         private int     last;
+         private int     offset;
+         private long    state;
+         private boolean consumed;
+ 
+         public Tokenizer() {
+             reset();
+         }
+ 
+         /**
+          * Resets for next reuse.
+          *
+          */
+         public void reset() {
+ 
+             last   = -1;
+             offset = -1;
+             state  = 0;
+         }
+ 
+         /**
+          * Returns a length of a token to match.
+          * @return
+          */
+         public int length() {
+             return offset;
+         }
+ 
+         /**
+          * Returns an index of the last matched token.
+          * @return
+          */
+         public int getLastMatch() {
+             return last;
+         }
+ 
+         /**
+          * Indicates whethe the last character has been consumed by the matcher.
+          * @return
+          */
+         public boolean isConsumed() {
+             return consumed;
+         }
+ 
+         /**
+          * Checks whether the specified bit is not set.
+          * @param bit
+          * @return
+          */
+         private boolean isZeroBit(int bit) {
+             return (state & (1L << bit)) == 0;
+         }
+ 
+         /**
+          * Sets the specified bit.
+          * @param bit
+          */
+         private void setBit(int bit) {
+             state |= (1L << bit);
+         }
+ 
+         /**
+          * Matches the specified character against tokens.
+          * @param ch
+          * @param tokens
+          * @return
+          */
+         public boolean next(char ch, char[][] tokens) {
+ 
+             // Use local variable for performance
+             int index = ++offset;
+             int len   = offset + 1;
+             int left  = 0;
+ 
+             consumed = false;
+ 
+             for (int i = tokens.length; --i >= 0; ) {
+                 if (isZeroBit(i)) {
+                     if (tokens[i][index] == ch) {
+                         consumed = true;
+ 
+                         if (tokens[i].length == len) {
+                             setBit(i);
+ 
+                             last = i;
+                         } else {
+                             ++left;
+                         }
+                     } else {
+                         setBit(i);
+                     }
+                 }
+             }
+ 
+             return left > 0;
+         }
+     }
  }
*** misc/hsqldb/src/org/hsqldb/HsqlNameManager.java	Wed Mar  2 14:50:48 2005
--- misc/build/hsqldb/src/org/hsqldb/HsqlNameManager.java	Thu Mar 31 10:35:27 2005
***************
*** 62,68 ****
  class HsqlNameManager {
  
      private static HsqlNameManager staticManager = new HsqlNameManager();
!     private static int             serialNumber  = 0;
      private int                    sysNumber     = 0;
  
      static HsqlName newHsqlSystemTableName(String name) {
--- 62,68 ----
  class HsqlNameManager {
  
      private static HsqlNameManager staticManager = new HsqlNameManager();
!     private int                    serialNumber  = 1;    // 0 is reserved in lookups
      private int                    sysNumber     = 0;
  
      static HsqlName newHsqlSystemTableName(String name) {
***************
*** 92,98 ****
  
      /**
       * Auto names are used for autogenerated indexes or anonymous constraints.
-      * Also the name of a pseudo-column is the autoname ""
       */
      HsqlName newAutoName(String type, String namepart) {
  
--- 92,97 ----
***************
*** 133,139 ****
  
          private HsqlName(HsqlNameManager man) {
              manager  = man;
!             hashCode = HsqlNameManager.serialNumber++;
          }
  
          private HsqlName(HsqlNameManager man, String name,
--- 132,138 ----
  
          private HsqlName(HsqlNameManager man) {
              manager  = man;
!             hashCode = manager.serialNumber++;
          }
  
          private HsqlName(HsqlNameManager man, String name,
*** misc/hsqldb/src/org/hsqldb/Index.java	Wed Mar  2 14:50:48 2005
--- misc/build/hsqldb/src/org/hsqldb/Index.java	Thu Mar 31 10:35:27 2005
***************
*** 253,259 ****
      /**
       * Insert a node into the index
       */
!     void insert(Row row, int offset) throws HsqlException {
  
          Node    n       = root,
                  x       = n;
--- 253,259 ----
      /**
       * Insert a node into the index
       */
!     void insert(Session session, Row row, int offset) throws HsqlException {
  
          Node    n       = root,
                  x       = n;
***************
*** 273,279 ****
                  break;
              }
  
!             compare = compareRowUnique(row, n.getRow());
  
              if (compare == 0) {
                  throw Trace.error(Trace.VIOLATION_OF_UNIQUE_INDEX,
--- 273,279 ----
                  break;
              }
  
!             compare = compareRowUnique(session, row, n.getRow());
  
              if (compare == 0) {
                  throw Trace.error(Trace.VIOLATION_OF_UNIQUE_INDEX,
***************
*** 523,529 ****
      RowIterator findFirstRow(Session session, Object[] rowdata,
                               int[] rowColMap) throws HsqlException {
  
!         Node node = findNotNull(rowdata, rowColMap, true);
  
          return node == null ? emptyIterator
                              : new IndexRowIterator(session, this, node);
--- 523,529 ----
      RowIterator findFirstRow(Session session, Object[] rowdata,
                               int[] rowColMap) throws HsqlException {
  
!         Node node = findNotNull(session, rowdata, rowColMap, true);
  
          return node == null ? emptyIterator
                              : new IndexRowIterator(session, this, node);
***************
*** 532,538 ****
      RowIterator findFirstRowForDelete(Session session, Object[] rowdata,
                                        int[] rowColMap) throws HsqlException {
  
!         Node node = findNotNull(rowdata, rowColMap, true);
  
          if (node == null) {
              return emptyIterator;
--- 532,538 ----
      RowIterator findFirstRowForDelete(Session session, Object[] rowdata,
                                        int[] rowColMap) throws HsqlException {
  
!         Node node = findNotNull(session, rowdata, rowColMap, true);
  
          if (node == null) {
              return emptyIterator;
***************
*** 547,553 ****
  
      public Row findRow(Session session, Row row) throws HsqlException {
  
!         Node node = search(row);
  
          return node == null ? null
                              : node.getRow();
--- 547,553 ----
  
      public Row findRow(Session session, Row row) throws HsqlException {
  
!         Node node = search(session, row);
  
          return node == null ? null
                              : node.getRow();
***************
*** 555,561 ****
  
      boolean exists(Session session, Object[] rowdata,
                     int[] rowColMap) throws HsqlException {
!         return findNotNull(rowdata, rowColMap, true) != null;
      }
  
      RowIterator emptyIterator() {
--- 555,561 ----
  
      boolean exists(Session session, Object[] rowdata,
                     int[] rowColMap) throws HsqlException {
!         return findNotNull(session, rowdata, rowColMap, true) != null;
      }
  
      RowIterator emptyIterator() {
***************
*** 571,577 ****
       * @return matching node or null
       * @throws HsqlException
       */
!     private Node findNotNull(Object[] rowdata, int[] rowColMap,
                               boolean first) throws HsqlException {
  
          Node x      = root, n;
--- 571,578 ----
       * @return matching node or null
       * @throws HsqlException
       */
!     private Node findNotNull(Session session, Object[] rowdata,
!                              int[] rowColMap,
                               boolean first) throws HsqlException {
  
          Node x      = root, n;
***************
*** 582,588 ****
          }
  
          while (x != null) {
!             int i = this.compareRowNonUnique(rowdata, rowColMap, x.getData());
  
              if (i == 0) {
                  if (first == false) {
--- 583,590 ----
          }
  
          while (x != null) {
!             int i = this.compareRowNonUnique(session, rowdata, rowColMap,
!                                              x.getData());
  
              if (i == 0) {
                  if (first == false) {
***************
*** 620,625 ****
--- 622,628 ----
       * @return node matching node
       * @throws HsqlException
       */
+ /*
      Node find(Object[] rowdata, int[] rowColMap) throws HsqlException {
  
          Node x = root;
***************
*** 638,643 ****
--- 641,647 ----
  
          return null;
      }
+ */
  
      /**
       * Determines if a table row has a null column for any of the columns given
***************
*** 691,697 ****
          boolean unique = isUnique &&!isNull(rowdata);
  
          while (x != null) {
!             int c = compareRowNonUnique(rowdata, colIndex, x.getData());
  
              if (c == 0) {
                  found = x;
--- 695,702 ----
          boolean unique = isUnique &&!isNull(rowdata);
  
          while (x != null) {
!             int c = compareRowNonUnique(session, rowdata, colIndex,
!                                         x.getData());
  
              if (c == 0) {
                  found = x;
***************
*** 751,758 ****
  */
          while (x != null) {
              boolean t =
!                 Column.compare(value, x.getData()[colIndex[0]], colType[0])
!                 >= iTest;
  
              if (t) {
                  Node r = x.getRight();
--- 756,764 ----
  */
          while (x != null) {
              boolean t =
!                 Column.compare(
!                     session.database.collation, value,
!                     x.getData()[colIndex[0]], colType[0]) >= iTest;
  
              if (t) {
                  Node r = x.getRight();
***************
*** 782,788 ****
  */
          while (x != null) {
              Object colvalue = x.getData()[colIndex[0]];
!             int    result   = Column.compare(value, colvalue, colType[0]);
  
              if (result >= iTest) {
                  x = next(x);
--- 788,795 ----
  */
          while (x != null) {
              Object colvalue = x.getData()[colIndex[0]];
!             int result = Column.compare(session.database.collation, value,
!                                         colvalue, colType[0]);
  
              if (result >= iTest) {
                  x = next(x);
***************
*** 818,825 ****
  
          while (x != null) {
              boolean t =
!                 Column.compare(null, x.getData()[colIndex[0]], colType[0])
!                 >= 0;
  
              if (t) {
                  Node r = x.getRight();
--- 825,833 ----
  
          while (x != null) {
              boolean t =
!                 Column.compare(
!                     session.database.collation, null,
!                     x.getData()[colIndex[0]], colType[0]) >= 0;
  
              if (t) {
                  Node r = x.getRight();
***************
*** 988,1000 ****
       *
       * @throws HsqlException
       */
!     Node search(Row row) throws HsqlException {
  
          Object[] d = row.getData();
          Node     x = root;
  
          while (x != null) {
!             int c = compareRowUnique(row, x.getRow());
  
              if (c == 0) {
                  return x;
--- 996,1008 ----
       *
       * @throws HsqlException
       */
!     Node search(Session session, Row row) throws HsqlException {
  
          Object[] d = row.getData();
          Node     x = root;
  
          while (x != null) {
!             int c = compareRowUnique(session, row, x.getRow());
  
              if (c == 0) {
                  return x;
***************
*** 1022,1031 ****
       * @return comparison result, -1,0,+1
       * @throws HsqlException
       */
!     int compareRowNonUnique(Object[] a, int[] rowColMap,
                              Object[] b) throws HsqlException {
  
!         int i = Column.compare(a[rowColMap[0]], b[colIndex[0]], colType[0]);
  
          if (i != 0) {
              return i;
--- 1030,1040 ----
       * @return comparison result, -1,0,+1
       * @throws HsqlException
       */
!     int compareRowNonUnique(Session session, Object[] a, int[] rowColMap,
                              Object[] b) throws HsqlException {
  
!         int i = Column.compare(session.database.collation, a[rowColMap[0]],
!                                b[colIndex[0]], colType[0]);
  
          if (i != 0) {
              return i;
***************
*** 1034,1040 ****
          int fieldcount = rowColMap.length;
  
          for (int j = 1; j < fieldcount; j++) {
!             i = Column.compare(a[rowColMap[j]], b[colIndex[j]], colType[j]);
  
              if (i != 0) {
                  return i;
--- 1043,1050 ----
          int fieldcount = rowColMap.length;
  
          for (int j = 1; j < fieldcount; j++) {
!             i = Column.compare(session.database.collation, a[rowColMap[j]],
!                                b[colIndex[j]], colType[j]);
  
              if (i != 0) {
                  return i;
***************
*** 1054,1066 ****
       * @return comparison result, -1,0,+1
       * @throws HsqlException
       */
!     static int compareRows(Object[] a, Object[] b, int[] cols,
!                            int[] coltypes) throws HsqlException {
  
          int fieldcount = cols.length;
  
          for (int j = 0; j < fieldcount; j++) {
!             int i = Column.compare(a[cols[j]], b[cols[j]], coltypes[j]);
  
              if (i != 0) {
                  return i;
--- 1064,1077 ----
       * @return comparison result, -1,0,+1
       * @throws HsqlException
       */
!     static int compareRows(Session session, Object[] a, Object[] b,
!                            int[] cols, int[] coltypes) throws HsqlException {
  
          int fieldcount = cols.length;
  
          for (int j = 0; j < fieldcount; j++) {
!             int i = Column.compare(session.database.collation, a[cols[j]],
!                                    b[cols[j]], coltypes[cols[j]]);
  
              if (i != 0) {
                  return i;
***************
*** 1080,1086 ****
       *
       * @throws HsqlException
       */
!     private int compareRowUnique(Row left, Row right) throws HsqlException {
  
          Object[] a       = left.getData();
          Object[] b       = right.getData();
--- 1091,1098 ----
       *
       * @throws HsqlException
       */
!     private int compareRowUnique(Session session, Row left,
!                                  Row right) throws HsqlException {
  
          Object[] a       = left.getData();
          Object[] b       = right.getData();
***************
*** 1089,1095 ****
  
          for (; j < colIndex.length; j++) {
              Object currentvalue = a[colIndex[j]];
!             int i = Column.compare(currentvalue, b[colIndex[j]], colType[j]);
  
              if (i != 0) {
                  return i;
--- 1101,1108 ----
  
          for (; j < colIndex.length; j++) {
              Object currentvalue = a[colIndex[j]];
!             int i = Column.compare(session.database.collation, currentvalue,
!                                    b[colIndex[j]], colType[j]);
  
              if (i != 0) {
                  return i;
***************
*** 1106,1112 ****
  
          for (j = 0; j < pkCols.length; j++) {
              Object currentvalue = a[pkCols[j]];
!             int    i = Column.compare(currentvalue, b[pkCols[j]], pkTypes[j]);
  
              if (i != 0) {
                  return i;
--- 1119,1126 ----
  
          for (j = 0; j < pkCols.length; j++) {
              Object currentvalue = a[pkCols[j]];
!             int i = Column.compare(session.database.collation, currentvalue,
!                                    b[pkCols[j]], pkTypes[j]);
  
              if (i != 0) {
                  return i;
***************
*** 1161,1166 ****
--- 1175,1181 ----
  
      static class IndexRowIterator implements RowIterator {
  
+         Session                    session;
          Index                      index;
          Node                       nextnode;
          protected IndexRowIterator last;
***************
*** 1172,1177 ****
--- 1187,1193 ----
                  return;
              }
  
+             this.session  = session;
              this.index    = index;
              this.nextnode = node;
          }
*** misc/hsqldb/src/org/hsqldb/Library.java	Wed Mar  2 14:50:53 2005
--- misc/build/hsqldb/src/org/hsqldb/Library.java	Thu Mar 31 10:35:27 2005
***************
*** 87,92 ****
--- 87,93 ----
  // boucherb@user 20020918 - doc 1.7.2 - added JavaDoc  and code comments
  // fredt@user 20021021 - doc 1.7.2 - modified JavaDoc
  // boucherb@users 20030201 - patch 1.7.2 - direct calls for org.hsqldb.Library
+ //
  
  /**
   * fredt - todo - since the introduction of SQL built-in functions and
***************
*** 107,112 ****
--- 108,114 ----
   */
  public class Library {
  
+     static final SimpleDateFormat tocharFormat = new SimpleDateFormat();
      static final SimpleDateFormat daynameFormat = new SimpleDateFormat("EEEE",
          Locale.ENGLISH);
      static final SimpleDateFormat monthnameFormat =
***************
*** 271,276 ****
--- 273,280 ----
              "WEEK", "org.hsqldb.Library.week"
          }, {
              "YEAR", "org.hsqldb.Library.year"
+         }, {
+             "TO_CHAR", "org.hsqldb.Library.to_char"
          }
      };
      public static final String[][] sSystem   = {
***************
*** 1562,1567 ****
--- 1566,1584 ----
                  Calendar.YEAR));
      }
  
+     public static String to_char(java.util.Date d, String format) {
+ 
+         if (d == null || format == null) {
+             return null;
+         }
+ 
+         synchronized (tocharFormat) {
+             tocharFormat.applyPattern(HsqlDateTime.toJavaDatePattern(format));
+ 
+             return tocharFormat.format(d);
+         }
+     }
+ 
      // date calculations.
  
      /**
***************
*** 1893,1898 ****
--- 1910,1916 ----
      static final int soundex                   = 54;
      static final int space                     = 55;
      static final int substring                 = 56;
+     static final int to_char                   = 65;
      static final int trim                      = 57;
      static final int truncate                  = 58;
      static final int ucase                     = 59;
***************
*** 1968,1973 ****
--- 1986,1992 ----
          functionMap.put("soundex", soundex);
          functionMap.put("space", space);
          functionMap.put("substring", substring);
+         functionMap.put("to_char", to_char);
          functionMap.put("trim", trim);
          functionMap.put("truncate", truncate);
          functionMap.put("ucase", ucase);
***************
*** 2206,2211 ****
--- 2225,2233 ----
                  case year : {
                      return year((Date) params[0]);
                  }
+                 case to_char : {
+                     return to_char((Date) params[0], (String) params[1]);
+                 }
                  case isReadOnlyDatabaseFiles : {
                      return null;
                  }
*** misc/hsqldb/src/org/hsqldb/Like.java	Wed Mar  2 14:50:53 2005
--- misc/build/hsqldb/src/org/hsqldb/Like.java	Thu Mar 31 10:35:27 2005
***************
*** 85,96 ****
      private int      iFirstWildCard;
      private boolean  isNull;
      Character        escapeChar;
      boolean          optimised;
      static final int UNDERSCORE_CHAR = 1;
      static final int PERCENT_CHAR    = 2;
  
!     Like(Character escape) {
!         escapeChar = escape;
      }
  
      /**
--- 85,98 ----
      private int      iFirstWildCard;
      private boolean  isNull;
      Character        escapeChar;
+     boolean          hasCollation;
      boolean          optimised;
      static final int UNDERSCORE_CHAR = 1;
      static final int PERCENT_CHAR    = 2;
  
!     Like(Character escape, boolean collation) {
!         escapeChar   = escape;
!         hasCollation = collation;
      }
  
      /**
***************
*** 143,152 ****
       *
       * @return
       */
!     boolean compare(Object o) {
  
          if (o == null) {
!             return iLen == 0;
          }
  
          String s = o.toString();
--- 145,154 ----
       *
       * @return
       */
!     Boolean compare(Session session, Object o) {
  
          if (o == null) {
!             return null;
          }
  
          String s = o.toString();
***************
*** 155,161 ****
              s = s.toUpperCase();
          }
  
!         return compareAt(s, 0, 0, s.length());
      }
  
      /**
--- 157,164 ----
              s = s.toUpperCase();
          }
  
!         return compareAt(s, 0, 0, s.length()) ? Boolean.TRUE
!                                               : Boolean.FALSE;
      }
  
      /**
*** misc/hsqldb/src/org/hsqldb/Parser.java	Wed Mar  2 14:50:53 2005
--- misc/build/hsqldb/src/org/hsqldb/Parser.java	Thu Mar 31 10:35:27 2005
***************
*** 251,263 ****
  
          subQueryLevel++;
  
!         Select s = parseSelect(brackets, false, true);
  
          sq.level = subQueryLevel;
  
          subQueryLevel--;
  
!         boolean isResolved = s.resolveAll(resolveAll);
  
          sq.select     = s;
          sq.isResolved = isResolved;
--- 251,270 ----
  
          subQueryLevel++;
  
!         boolean canHaveOrder = predicateType == Expression.VIEW;
!         boolean limitWithOrder = predicateType == Expression.VIEW
!                                  || predicateType == Expression.QUERY
!                                  || predicateType == Expression.IN
!                                  || predicateType == Expression.ALL
!                                  || predicateType == Expression.ANY;
!         Select s = parseSelect(brackets, canHaveOrder, false, limitWithOrder,
!                                true);
  
          sq.level = subQueryLevel;
  
          subQueryLevel--;
  
!         boolean isResolved = s.resolveAll(database, resolveAll);
  
          sq.select     = s;
          sq.isResolved = isResolved;
***************
*** 299,311 ****
  
          table.addColumns(s);
  
!         int[] pcol = predicateType == Expression.IN ? new int[]{ 0 }
!                                                     : null;
  
          table.createPrimaryKey(pcol);
  
!         sq.table         = table;
!         sq.isInPredicate = predicateType == Expression.IN;
  
          subQueryList.add(sq);
  
--- 306,321 ----
  
          table.addColumns(s);
  
!         boolean uniqueValues = predicateType == Expression.IN
!                                || predicateType == Expression.ALL
!                                || predicateType == Expression.ANY;
!         int[] pcol = uniqueValues ? new int[]{ 0 }
!                                   : null;
  
          table.createPrimaryKey(pcol);
  
!         sq.table      = table;
!         sq.uniqueRows = uniqueValues;
  
          subQueryList.add(sq);
  
***************
*** 333,348 ****
       * @return a new Select object
       * @throws  HsqlException if a parsing error occurs
       */
!     Select parseSelect(int brackets, boolean hasOrder,
                         boolean isMain) throws HsqlException {
  
          Select select = new Select();
  
!         if (hasOrder) {
!             parseLimit(select);
!         }
  
!         String token = tokenizer.getString();
  
          if (token.equals(Token.T_DISTINCT)) {
              select.isDistinctSelect = true;
--- 343,362 ----
       * @return a new Select object
       * @throws  HsqlException if a parsing error occurs
       */
!     Select parseSelect(int brackets, boolean canHaveOrder,
!                        boolean canHaveLimit, boolean limitWithOrder,
                         boolean isMain) throws HsqlException {
  
          Select select = new Select();
+         String token  = tokenizer.getString();
  
!         if (canHaveLimit || limitWithOrder) {
!             if (token.equals(Token.T_LIMIT) || token.equals(Token.T_TOP)) {
!                 parseLimit(token, select, false);
  
!                 token = tokenizer.getString();
!             }
!         }
  
          if (token.equals(Token.T_DISTINCT)) {
              select.isDistinctSelect = true;
***************
*** 485,490 ****
--- 499,505 ----
  
          select.queryCondition = condition;
  
+         // group by
          if (token.equals(Token.T_GROUP)) {
              tokenizer.getThis(Token.T_BY);
  
***************
*** 493,501 ****
              do {
                  Expression e = parseExpression();
  
-                 // tony_lai@users having support:
-                 // "group by" does not allow refering to other columns alias.
-                 //e = doOrderGroup(e, vcolumn);
                  vcolumn.add(e);
  
                  token = tokenizer.getString();
--- 508,513 ----
***************
*** 506,522 ****
              select.iGroupLen = len;
          }
  
!         // tony_lai@users - having support
!         // fredt - this one does not go through resolve, etc.
          if (token.equals(Token.T_HAVING)) {
!             select.iHavingIndex    = vcolumn.size();
              select.havingCondition = parseExpression();
              token                  = tokenizer.getString();
  
              vcolumn.add(select.havingCondition);
          }
  
          if (brackets > 0 && token.equals(Token.T_CLOSEBRACKET)) {
              brackets -= Parser.parseCloseBrackets(tokenizer, brackets - 1)
                          + 1;
              token = tokenizer.getString();
--- 518,551 ----
              select.iGroupLen = len;
          }
  
!         // having
          if (token.equals(Token.T_HAVING)) {
!             select.iHavingLen      = 1;
              select.havingCondition = parseExpression();
              token                  = tokenizer.getString();
  
              vcolumn.add(select.havingCondition);
          }
  
+         if (isMain || limitWithOrder) {
+             if (token.equals(Token.T_ORDER)) {
+                 tokenizer.getThis(Token.T_BY);
+                 parseOrderBy(select, vcolumn);
+ 
+                 token = tokenizer.getString();
+             }
+ 
+             if (token.equals(Token.T_LIMIT)) {
+                 parseLimit(token, select, true);
+ 
+                 token = tokenizer.getString();
+             }
+         }
+ 
+         boolean closebrackets = false;
+ 
          if (brackets > 0 && token.equals(Token.T_CLOSEBRACKET)) {
+             closebrackets = true;
              brackets -= Parser.parseCloseBrackets(tokenizer, brackets - 1)
                          + 1;
              token = tokenizer.getString();
***************
*** 524,554 ****
  
          select.unionDepth = brackets;
  
          int unionType = parseUnion(token);
  
          if (unionType != Select.NOUNION) {
              select.unionType = unionType;
  
              if (tokenizer.isGetThis(Token.T_OPENBRACKET)) {
!                 brackets += Parser.parseOpenBrackets(tokenizer) + 1;
              }
  
              tokenizer.getThis(Token.T_SELECT);
  
!             select.unionSelect = parseSelect(brackets, false, false);
!         }
! 
!         if (hasOrder) {
              token = tokenizer.getString();
  
              if (token.equals(Token.T_ORDER)) {
                  tokenizer.getThis(Token.T_BY);
                  parseOrderBy(select, vcolumn);
!             } else {
!                 tokenizer.back();
              }
          }
  
          if (isMain) {
              select.prepareUnions();
          }
--- 553,617 ----
  
          select.unionDepth = brackets;
  
+         // checks for ORDER and LIMIT
+         if (!(isMain || closebrackets)) {
+             limitWithOrder = false;
+         }
+ 
+         if (!canHaveOrder &&!limitWithOrder && select.iOrderLen != 0) {
+             throw Trace.error(Trace.INVALID_ORDER_BY);
+         }
+ 
+         if (!canHaveLimit &&!limitWithOrder
+                 && select.limitCondition != null) {
+             throw Trace.error(Trace.INVALID_LIMIT);
+         }
+ 
+         if (limitWithOrder
+                 && ((select.limitCondition == null)
+                     ^ (select.iOrderLen == 0))) {
+             throw Trace.error(Trace.ORDER_LIMIT_REQUIRED);
+         }
+ 
          int unionType = parseUnion(token);
  
          if (unionType != Select.NOUNION) {
+             boolean openbracket = false;
+ 
              select.unionType = unionType;
  
              if (tokenizer.isGetThis(Token.T_OPENBRACKET)) {
!                 openbracket = true;
!                 brackets    += Parser.parseOpenBrackets(tokenizer) + 1;
              }
  
              tokenizer.getThis(Token.T_SELECT);
  
!             // accept ORDRY BY with LIMIT
!             select.unionSelect = parseSelect(brackets, false, false,
!                                              openbracket, false);
              token = tokenizer.getString();
+         }
  
+         if (isMain && (canHaveOrder || limitWithOrder)
+                 && select.iOrderLen == 0) {
              if (token.equals(Token.T_ORDER)) {
                  tokenizer.getThis(Token.T_BY);
                  parseOrderBy(select, vcolumn);
! 
!                 token            = tokenizer.getString();
!                 select.sortUnion = true;
!             }
! 
!             if (token.equals(Token.T_LIMIT)) {
!                 parseLimit(token, select, true);
! 
!                 token = tokenizer.getString();
              }
          }
  
+         tokenizer.back();
+ 
          if (isMain) {
              select.prepareUnions();
          }
***************
*** 600,606 ****
                  break;
  
              default :
-                 tokenizer.back();
                  break;
          }
  
--- 663,668 ----
***************
*** 615,628 ****
  // in other RDBMS's
  // "SELECT LIMIT n 0" discards the first n rows and returns the remaining rows
  // fredt@users 20020225 - patch 456679 by hiep256 - TOP keyword
!     private void parseLimit(Select select) throws HsqlException {
  
!         String     token = tokenizer.getString();
!         Expression e1;
          Expression e2;
          boolean    islimit = false;
  
!         if (token.equals(Token.T_LIMIT)) {
              read();
  
              e1      = readTerm();
--- 677,712 ----
  // in other RDBMS's
  // "SELECT LIMIT n 0" discards the first n rows and returns the remaining rows
  // fredt@users 20020225 - patch 456679 by hiep256 - TOP keyword
!     private void parseLimit(String token, Select select,
!                             boolean isEnd) throws HsqlException {
  
!         if (select.limitCondition != null) {
!             return;
!         }
! 
!         Expression e1 = null;
          Expression e2;
          boolean    islimit = false;
  
!         if (isEnd) {
!             if (token.equals(Token.T_LIMIT)) {
!                 islimit = true;
! 
!                 read();
! 
!                 e2 = readTerm();
! 
!                 if (sToken.equals(Token.T_OFFSET)) {
!                     read();
! 
!                     e1 = readTerm();
!                 }
! 
!                 tokenizer.back();
!             } else {
!                 return;
!             }
!         } else if (token.equals(Token.T_LIMIT)) {
              read();
  
              e1      = readTerm();
***************
*** 633,648 ****
          } else if (token.equals(Token.T_TOP)) {
              read();
  
-             e1 = new Expression(Types.INTEGER, ValuePool.getInt(0));
              e2 = readTerm();
  
              tokenizer.back();
          } else {
-             tokenizer.back();
- 
              return;
          }
  
          if ((e1.getType() == Expression.VALUE && e1.getDataType() == Types
                  .INTEGER && ((Integer) e1.getValue(null))
                  .intValue() >= 0) || e1.isParam()) {
--- 717,733 ----
          } else if (token.equals(Token.T_TOP)) {
              read();
  
              e2 = readTerm();
  
              tokenizer.back();
          } else {
              return;
          }
  
+         if (e1 == null) {
+             e1 = new Expression(Types.INTEGER, ValuePool.getInt(0));
+         }
+ 
          if ((e1.getType() == Expression.VALUE && e1.getDataType() == Types
                  .INTEGER && ((Integer) e1.getValue(null))
                  .intValue() >= 0) || e1.isParam()) {
***************
*** 661,668 ****
              }
          }
  
!         int messageid = islimit ? Trace.Parser_parseLimit1
!                                 : Trace.Parser_parseLimit2;
  
          throw Trace.error(Trace.WRONG_DATA_TYPE, messageid);
      }
--- 746,753 ----
              }
          }
  
!         int messageid = islimit ? Trace.INVALID_LIMIT_EXPRESSION
!                                 : Trace.INVALID_TOP_EXPRESSION;
  
          throw Trace.error(Trace.WRONG_DATA_TYPE, messageid);
      }
***************
*** 676,683 ****
          do {
              Expression e = parseExpression();
  
!             e = resolveOrderByColumnAlias(e, vcolumn, select.iResultLen,
!                                           select.unionSelect != null);
              token = tokenizer.getString();
  
              if (token.equals(Token.T_DESC)) {
--- 761,767 ----
          do {
              Expression e = parseExpression();
  
!             e     = resolveOrderByExpression(e, select, vcolumn);
              token = tokenizer.getString();
  
              if (token.equals(Token.T_DESC)) {
***************
*** 698,706 ****
          select.iOrderLen = len;
      }
  
!     private static void resolveSelectTableFilter(Select select,
!             HsqlArrayList vcolumn,
!             HsqlArrayList vfilter) throws HsqlException {
  
          int           len     = vfilter.size();
          TableFilter[] filters = new TableFilter[len];
--- 782,791 ----
          select.iOrderLen = len;
      }
  
!     private void resolveSelectTableFilter(Select select,
!                                           HsqlArrayList vcolumn,
!                                           HsqlArrayList vfilter)
!                                           throws HsqlException {
  
          int           len     = vfilter.size();
          TableFilter[] filters = new TableFilter[len];
***************
*** 751,757 ****
                  len--;
  
                  vcolumn.remove(current);
!             } else if (e.getType() == Expression.COLUMN) {
                  if (e.getFilter() == null) {
                      for (int f = 0; f < filters.length; f++) {
                          e.resolveTables(filters[f]);
--- 836,842 ----
                  len--;
  
                  vcolumn.remove(current);
!             } else /* if (e.getType() == Expression.COLUMN) */ {
                  if (e.getFilter() == null) {
                      for (int f = 0; f < filters.length; f++) {
                          e.resolveTables(filters[f]);
***************
*** 763,769 ****
          for (int i = 0; i < len; i++) {
              Expression e = (Expression) (vcolumn.get(i));
  
!             e.resolveTypes();
          }
  
          select.iResultLen = len;
--- 848,854 ----
          for (int i = 0; i < len; i++) {
              Expression e = (Expression) (vcolumn.get(i));
  
!             e.resolveTypes(database);
          }
  
          select.iResultLen = len;
***************
*** 799,807 ****
       * @throws HsqlException if an ambiguous reference to an alias or
       *      non-integer column index is encountered
       */
!     private static Expression resolveOrderByColumnAlias(Expression e,
!             HsqlArrayList vcolumn, int visiblecols,
!             boolean union) throws HsqlException {
  
          if (e.getType() == Expression.VALUE) {
              return resolveOrderByColumnIndex(e, vcolumn, visiblecols);
--- 884,894 ----
       * @throws HsqlException if an ambiguous reference to an alias or
       *      non-integer column index is encountered
       */
!     private static Expression resolveOrderByExpression(Expression e,
!             Select select, HsqlArrayList vcolumn) throws HsqlException {
! 
!         int     visiblecols = select.iResultLen;
!         boolean union       = select.unionSelect != null;
  
          if (e.getType() == Expression.VALUE) {
              return resolveOrderByColumnIndex(e, vcolumn, visiblecols);
***************
*** 815,880 ****
              return e;
          }
  
!         String ordercolname   = e.getColumnName();
!         String ordertablename = e.getTableName();
! 
!         // fully qualified column specification
!         if (ordertablename != null) {
!             for (int i = 0, size = visiblecols; i < size; i++) {
!                 Expression colexpr = (Expression) vcolumn.get(i);
! 
!                 if (ordercolname.equals(colexpr.getColumnName())
!                         && ordertablename.endsWith(colexpr.getTableName())) {
!                     colexpr.orderColumnIndex = i;
! 
!                     return colexpr;
!                 }
!             }
! 
!             if (union) {
!                 throw Trace.error(Trace.INVALID_ORDER_BY, ordercolname);
!             }
! 
!             return e;
!         }
! 
!         // column name only
!         Expression found = e;
  
!         for (int i = 0, size = vcolumn.size(); i < size; i++) {
!             Expression colexpr  = (Expression) vcolumn.get(i);
!             String     colalias = colexpr.getDefinedAlias();
!             String     colname  = colexpr.getColumnName();
! 
!             if (ordercolname.equals(colalias)
!                     || ordercolname.equals(colname)) {
! 
!                 // check for ambiguity if two displayed cols have the same name
!                 // do not check beyond as a column may be repeated for grouping purposes
!                 if (found != e && i < visiblecols) {
!                     throw Trace.error(Trace.AMBIGUOUS_COLUMN_REFERENCE,
!                                       ordercolname);
!                 }
! 
!                 // choose the first expression
!                 if (found == e) {
!                     found = colexpr;
  
!                     // set this for use in sorting
!                     found.orderColumnIndex = i;
!                 }
              }
          }
  
          if (union) {
!             if (found == e || found.orderColumnIndex >= visiblecols) {
! 
!                 // no column in select list is found
!                 throw Trace.error(Trace.INVALID_ORDER_BY, ordercolname);
!             }
          }
  
!         return found;
      }
  
      private static Expression resolveOrderByColumnIndex(Expression e,
--- 902,931 ----
              return e;
          }
  
!         String ecolname   = e.getColumnName();
!         String etablename = e.getTableName();
  
!         for (int i = 0, size = visiblecols; i < size; i++) {
!             Expression colexpr    = (Expression) vcolumn.get(i);
!             String     colalias   = colexpr.getDefinedAlias();
!             String     colname    = colexpr.getColumnName();
!             String     tablename  = colexpr.getTableName();
!             String     filtername = colexpr.getFilterTableName();
! 
!             if ((ecolname.equals(colalias) || ecolname.equals(colname))
!                     && (etablename == null || etablename.equals(tablename)
!                         || etablename.equals(filtername))) {
!                 colexpr.joinedTableColumnIndex = i;
  
!                 return colexpr;
              }
          }
  
          if (union) {
!             throw Trace.error(Trace.INVALID_ORDER_BY, ecolname);
          }
  
!         return e;
      }
  
      private static Expression resolveOrderByColumnIndex(Expression e,
***************
*** 887,893 ****
              if (0 < i && i <= visiblecols) {
                  Expression colexpr = (Expression) vcolumn.get(i - 1);
  
!                 colexpr.orderColumnIndex = i - 1;
  
                  return colexpr;
              }
--- 938,944 ----
              if (0 < i && i <= visiblecols) {
                  Expression colexpr = (Expression) vcolumn.get(i - 1);
  
!                 colexpr.joinedTableColumnIndex = i - 1;
  
                  return colexpr;
              }
***************
*** 1281,1287 ****
              escape = new Character(s.charAt(0));
          }
  
!         a = new Expression(a, b, escape);
  
          return a;
      }
--- 1332,1340 ----
              escape = new Character(s.charAt(0));
          }
  
!         boolean hasCollation = database.collation.name != null;
! 
!         a = new Expression(a, b, escape, hasCollation);
  
          return a;
      }
***************
*** 1370,1375 ****
--- 1423,1462 ----
          return new Expression(type, a, b);
      }
  
+     private Expression parseAllAnyPredicate() throws HsqlException {
+ 
+         int type = iToken;
+ 
+         read();
+         readThis(Expression.OPEN);
+ 
+         Expression b        = null;
+         int        brackets = 0;
+ 
+         if (iToken == Expression.OPEN) {
+             brackets += Parser.parseOpenBrackets(tokenizer) + 1;
+ 
+             read();
+         }
+ 
+         if (iToken != Expression.SELECT) {
+             throw Trace.error(Trace.INVALID_IDENTIFIER);
+         }
+ 
+         SubQuery sq     = parseSubquery(brackets, null, false, type);
+         Select   select = sq.select;
+ 
+         // until we support rows
+         Trace.check(select.iResultLen == 1, Trace.SINGLE_COLUMN_EXPECTED);
+ 
+         b = new Expression(select, sq.table, !sq.isResolved);
+ 
+         read();
+         readThis(Expression.CLOSE);
+ 
+         return new Expression(type, b, null);
+     }
+ 
      /**
       *  Method declaration
       *
***************
*** 1539,1547 ****
                  break;
              }
              case Expression.SELECT : {
-                 Select select = parseSelect(0, true, true);
  
!                 select.resolve();
  
                  r = new Expression(select, null, true);
  
--- 1626,1636 ----
                  break;
              }
              case Expression.SELECT : {
  
!                 // accept ORDRY BY with LIMIT
!                 Select select = parseSelect(0, false, false, true, true);
! 
!                 select.resolve(database);
  
                  r = new Expression(select, null, true);
  
***************
*** 1549,1554 ****
--- 1638,1650 ----
  
                  break;
              }
+             case Expression.ANY :
+             case Expression.ALL : {
+                 r = parseAllAnyPredicate();
+ 
+ //                read();
+                 break;
+             }
              case Expression.MULTIPLY : {
                  r = new Expression(sTable, (String) null);
  
***************
*** 1734,1739 ****
--- 1830,1839 ----
              tokenizer.getThis(Token.T_CLOSEBRACKET);
          }
  
+         if (t == Types.FLOAT && p > 53) {
+             throw Trace.error(Trace.NUMERIC_VALUE_OUT_OF_RANGE);
+         }
+ 
          if (r.isParam()) {
              r.setDataType(t);
          }
***************
*** 2148,2153 ****
--- 2248,2255 ----
                  case Expression.AND :
                  case Expression.OR :
                  case Expression.NOT :
+                 case Expression.ALL :
+                 case Expression.ANY :
                  case Expression.IN :
                  case Expression.EXISTS :
                  case Expression.BETWEEN :
***************
*** 2196,2201 ****
--- 2298,2304 ----
                  case Expression.BOTH :
                  case Expression.AS :
                  case Expression.IS :
+                 case Expression.DISTINCT :
                      break;            // nothing else required, iToken initialized properly
  
                  case Expression.MULTIPLY :
***************
*** 2233,2238 ****
--- 2336,2344 ----
          tokenSet.put(Token.T_AND, Expression.AND);
          tokenSet.put(Token.T_NOT, Expression.NOT);
          tokenSet.put(Token.T_OR, Expression.OR);
+         tokenSet.put(Token.T_ALL, Expression.ALL);
+ 
+ //        tokenSet.put(Token.T_ANY, Expression.ANY); todo
          tokenSet.put(Token.T_IN, Expression.IN);
          tokenSet.put(Token.T_EXISTS, Expression.EXISTS);
          tokenSet.put(Token.T_BETWEEN, Expression.BETWEEN);
***************
*** 2257,2262 ****
--- 2363,2369 ----
          tokenSet.put(Token.T_VAR_POP, Expression.VAR_POP);
          tokenSet.put(Token.T_VAR_SAMP, Expression.VAR_SAMP);
          tokenSet.put(Token.T_IFNULL, Expression.IFNULL);
+         tokenSet.put(Token.T_NVL, Expression.IFNULL);
          tokenSet.put(Token.T_NULLIF, Expression.NULLIF);
          tokenSet.put(Token.T_CONVERT, Expression.CONVERT);
          tokenSet.put(Token.T_CAST, Expression.CAST);
***************
*** 2348,2354 ****
          clearParameters();
  
          Expression expression = parseExpression();
!         CompiledStatement cs = new CompiledStatement(expression,
              getParameters());
  
          cs.subqueries = getSortedSubqueries();
--- 2455,2461 ----
          clearParameters();
  
          Expression expression = parseExpression();
!         CompiledStatement cs = new CompiledStatement(database, expression,
              getParameters());
  
          cs.subqueries = getSortedSubqueries();
***************
*** 2377,2384 ****
              tokenizer.back();
          }
  
!         CompiledStatement cs = new CompiledStatement(tableFilter, condition,
!             getParameters());
  
          cs.subqueries = getSortedSubqueries();
  
--- 2484,2491 ----
              tokenizer.back();
          }
  
!         CompiledStatement cs = new CompiledStatement(database, tableFilter,
!             condition, getParameters());
  
          cs.subqueries = getSortedSubqueries();
  
***************
*** 2403,2409 ****
  
  //            cve.resolve(null);
              cve.resolveTables(null);
!             cve.resolveTypes();
  
              acve[i] = cve;
              token   = tokenizer.getString();
--- 2510,2516 ----
  
  //            cve.resolve(null);
              cve.resolveTables(null);
!             cve.resolveTypes(database);
  
              acve[i] = cve;
              token   = tokenizer.getString();
***************
*** 2499,2511 ****
                  tokenizer.getThis(Token.T_SELECT);
              }
              case Token.SELECT : {
!                 Select select = parseSelect(brackets, true, true);
  
                  if (len != select.iResultLen) {
                      throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH);
                  }
  
!                 CompiledStatement cs = new CompiledStatement(table,
                      columnMap, columnCheckList, select, getParameters());
  
                  cs.subqueries = getSortedSubqueries();
--- 2606,2621 ----
                  tokenizer.getThis(Token.T_SELECT);
              }
              case Token.SELECT : {
! 
!                 // accept ORDER BY or ORDRY BY with LIMIT
!                 Select select = parseSelect(brackets, true, false, true,
!                                             true);
  
                  if (len != select.iResultLen) {
                      throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH);
                  }
  
!                 CompiledStatement cs = new CompiledStatement(database, table,
                      columnMap, columnCheckList, select, getParameters());
  
                  cs.subqueries = getSortedSubqueries();
***************
*** 2529,2535 ****
  
          clearParameters();
  
!         select = parseSelect(brackets, true, true);
  
          if (select.sIntoTable != null) {
              session.checkDDLWrite();
--- 2639,2645 ----
  
          clearParameters();
  
!         select = parseSelect(brackets, true, true, false, true);
  
          if (select.sIntoTable != null) {
              session.checkDDLWrite();
***************
*** 2541,2547 ****
              }
          }
  
!         CompiledStatement cs = new CompiledStatement(select, getParameters());
  
          cs.subqueries = getSortedSubqueries();
  
--- 2651,2658 ----
              }
          }
  
!         CompiledStatement cs = new CompiledStatement(database, select,
!             getParameters());
  
          cs.subqueries = getSortedSubqueries();
  
***************
*** 2605,2612 ****
          colList  = (int[]) ArrayUtil.resizeArray(colList, len);
          exprList = (Expression[]) ArrayUtil.resizeArray(exprList, len);
  
!         CompiledStatement cs = new CompiledStatement(tableFilter, colList,
!             exprList, condition, getParameters());
  
          cs.subqueries = getSortedSubqueries();
  
--- 2716,2723 ----
          colList  = (int[]) ArrayUtil.resizeArray(colList, len);
          exprList = (Expression[]) ArrayUtil.resizeArray(exprList, len);
  
!         CompiledStatement cs = new CompiledStatement(database, tableFilter,
!             colList, exprList, condition, getParameters());
  
          cs.subqueries = getSortedSubqueries();
  
*** misc/hsqldb/src/org/hsqldb/Result.java	Wed Mar  2 14:50:54 2005
--- misc/build/hsqldb/src/org/hsqldb/Result.java	Thu Mar 31 10:35:27 2005
***************
*** 839,846 ****
       *
       * @throws  HsqlException
       */
!     void removeDuplicates() throws HsqlException {
!         removeDuplicates(significantColumns);
      }
  
      /**
--- 839,846 ----
       *
       * @throws  HsqlException
       */
!     void removeDuplicates(Session session) throws HsqlException {
!         removeDuplicates(session, significantColumns);
      }
  
      /**
***************
*** 852,858 ****
  
  // fredt@users 20020130 - patch 1.7.0 by fredt
  // to ensure consistency of r.rTail r.iSize in all set operations
!     void removeDuplicates(int columnCount) throws HsqlException {
  
          if (rRoot == null) {
              return;
--- 852,859 ----
  
  // fredt@users 20020130 - patch 1.7.0 by fredt
  // to ensure consistency of r.rTail r.iSize in all set operations
!     void removeDuplicates(Session session,
!                           int columnCount) throws HsqlException {
  
          if (rRoot == null) {
              return;
***************
*** 866,872 ****
              way[i]   = 1;
          }
  
!         sortResult(order, way);
  
          Record n = rRoot;
  
--- 867,873 ----
              way[i]   = 1;
          }
  
!         sortResult(session, order, way);
  
          Record n = rRoot;
  
***************
*** 877,883 ****
                  break;
              }
  
!             if (compareRecord(n.data, next.data, columnCount) == 0) {
                  n.next = next.next;
  
                  size--;
--- 878,884 ----
                  break;
              }
  
!             if (compareRecord(session, n.data, next.data, columnCount) == 0) {
                  n.next = next.next;
  
                  size--;
***************
*** 896,905 ****
       * @param  minus
       * @throws  HsqlException
       */
!     void removeSecond(Result minus, int columnCount) throws HsqlException {
  
!         removeDuplicates(columnCount);
!         minus.removeDuplicates(columnCount);
  
          Record  n     = rRoot;
          Record  last  = rRoot;
--- 897,907 ----
       * @param  minus
       * @throws  HsqlException
       */
!     void removeSecond(Session session, Result minus,
!                       int columnCount) throws HsqlException {
  
!         removeDuplicates(session, columnCount);
!         minus.removeDuplicates(session, columnCount);
  
          Record  n     = rRoot;
          Record  last  = rRoot;
***************
*** 908,914 ****
          int     i     = 0;
  
          while (n != null && n2 != null) {
!             i = compareRecord(n.data, n2.data, columnCount);
  
              if (i == 0) {
                  if (rootr) {
--- 910,916 ----
          int     i     = 0;
  
          while (n != null && n2 != null) {
!             i = compareRecord(session, n.data, n2.data, columnCount);
  
              if (i == 0) {
                  if (rootr) {
***************
*** 945,954 ****
       * @param  r2
       * @throws  HsqlException
       */
!     void removeDifferent(Result r2, int columnCount) throws HsqlException {
  
!         removeDuplicates(columnCount);
!         r2.removeDuplicates(columnCount);
  
          Record  n     = rRoot;
          Record  last  = rRoot;
--- 947,957 ----
       * @param  r2
       * @throws  HsqlException
       */
!     void removeDifferent(Session session, Result r2,
!                          int columnCount) throws HsqlException {
  
!         removeDuplicates(session, columnCount);
!         r2.removeDuplicates(session, columnCount);
  
          Record  n     = rRoot;
          Record  last  = rRoot;
***************
*** 959,965 ****
          size = 0;
  
          while (n != null && n2 != null) {
!             i = compareRecord(n.data, n2.data, columnCount);
  
              if (i == 0) {             // same rows
                  if (rootr) {
--- 962,968 ----
          size = 0;
  
          while (n != null && n2 != null) {
!             i = compareRecord(session, n.data, n2.data, columnCount);
  
              if (i == 0) {             // same rows
                  if (rootr) {
***************
*** 998,1004 ****
       * @param  way
       * @throws  HsqlException
       */
!     void sortResult(final int[] order, final int[] way) throws HsqlException {
  
          if (rRoot == null || rRoot.next == null) {
              return;
--- 1001,1008 ----
       * @param  way
       * @throws  HsqlException
       */
!     void sortResult(Session session, final int[] order,
!                     final int[] way) throws HsqlException {
  
          if (rRoot == null || rRoot.next == null) {
              return;
***************
*** 1043,1050 ****
                          source0 = source0.next;
  
                          n0--;
!                     } else if (compareRecord(
!                             source0.data, source1.data, order, way) > 0) {
                          n       = source1;
                          source1 = source1.next;
  
--- 1047,1054 ----
                          source0 = source0.next;
  
                          n0--;
!                     } else if (compareRecord(session, source0.data, source1
!                             .data, order, way) > 0) {
                          n       = source1;
                          source1 = source1.next;
  
***************
*** 1082,1098 ****
       * @return -1, 0, +1
       * @throws  HsqlException
       */
!     private int compareRecord(Object[] a, final Object[] b,
                                final int[] order,
                                int[] way) throws HsqlException {
  
!         int i = Column.compare(a[order[0]], b[order[0]],
!                                metaData.colTypes[order[0]]);
  
          if (i == 0) {
              for (int j = 1; j < order.length; j++) {
!                 i = Column.compare(a[order[j]], b[order[j]],
!                                    metaData.colTypes[order[j]]);
  
                  if (i != 0) {
                      return i * way[j];
--- 1086,1102 ----
       * @return -1, 0, +1
       * @throws  HsqlException
       */
!     private int compareRecord(Session session, Object[] a, final Object[] b,
                                final int[] order,
                                int[] way) throws HsqlException {
  
!         int i = Column.compare(session.database.collation, a[order[0]],
!                                b[order[0]], metaData.colTypes[order[0]]);
  
          if (i == 0) {
              for (int j = 1; j < order.length; j++) {
!                 i = Column.compare(session.database.collation, a[order[j]],
!                                    b[order[j]], metaData.colTypes[order[j]]);
  
                  if (i != 0) {
                      return i * way[j];
***************
*** 1112,1122 ****
       * @return -1, 0, +1
       * @throws  HsqlException
       */
!     private int compareRecord(Object[] a, Object[] b,
                                int len) throws HsqlException {
  
          for (int j = 0; j < len; j++) {
!             int i = Column.compare(a[j], b[j], metaData.colTypes[j]);
  
              if (i != 0) {
                  return i;
--- 1116,1127 ----
       * @return -1, 0, +1
       * @throws  HsqlException
       */
!     private int compareRecord(Session session, Object[] a, Object[] b,
                                int len) throws HsqlException {
  
          for (int j = 0; j < len; j++) {
!             int i = Column.compare(session.database.collation, a[j], b[j],
!                                    metaData.colTypes[j]);
  
              if (i != 0) {
                  return i;
***************
*** 1126,1131 ****
--- 1131,1155 ----
          return 0;
      }
  
+     /**
+      * Result structure used for set/get session attributes
+      */
+     static Result newSessionAttributesResult() {
+ 
+         Result r = new Result(ResultConstants.DATA, 7);
+ 
+         r.metaData.colNames = r.metaData.colLabels = r.metaData.tableNames =
+             new String[] {
+             "", "", "", "", "", "", ""
+         };
+         r.metaData.colTypes = new int[] {
+             Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.INTEGER,
+             Types.BOOLEAN, Types.BOOLEAN, Types.BOOLEAN
+         };
+ 
+         return r;
+     }
+ 
      void write(RowOutputBinary out) throws IOException, HsqlException {
  
          if (mode == ResultConstants.MULTI) {
*** misc/hsqldb/src/org/hsqldb/ResultConstants.java	Wed Mar  2 14:50:54 2005
--- misc/build/hsqldb/src/org/hsqldb/ResultConstants.java	Thu Mar 31 10:35:27 2005
***************
*** 109,114 ****
--- 109,120 ----
       */
      int BATCHEXECUTE = HSQL_API_BASE + 9;
  
+     /**
+      * Indicates that the Result object encapsulates a batch of prepared
+      * statement parameter values
+      */
+     int HSQLRESETSESSION = HSQL_API_BASE + 10;
+ 
      /** The offset at which the standard SQL API Result mode values start. */
      int SQL_API_BASE = 0x00010000;
  
*** misc/hsqldb/src/org/hsqldb/Row.java	Wed Mar  2 14:50:54 2005
--- misc/build/hsqldb/src/org/hsqldb/Row.java	Thu Mar 31 10:35:27 2005
***************
*** 84,89 ****
--- 84,90 ----
   */
  public class Row implements CachedObject {
  
+     int                tableId;
      int                iPos;
      protected Object[] oData;
      protected Node     nPrimaryNode;
***************
*** 110,116 ****
              n       = n.nNext;
          }
  
!         oData = o;
      }
  
      /**
--- 111,118 ----
              n       = n.nNext;
          }
  
!         tableId = t.getId();
!         oData   = o;
      }
  
      /**
***************
*** 192,197 ****
--- 194,203 ----
          return 0;
      }
  
+     public long getId() {
+         return ((long) tableId << 32) + (((long) iPos) & 0xffffffffL);
+     }
+ 
      public int getPos() {
          return iPos;
      }
*** misc/hsqldb/src/org/hsqldb/Select.java	Wed Mar  2 14:50:55 2005
--- misc/build/hsqldb/src/org/hsqldb/Select.java	Thu Mar 31 10:35:27 2005
***************
*** 101,122 ****
      private HashSet       groupColumnNames;
      TableFilter[]         tFilter;
      Expression            limitCondition;
!     Expression            queryCondition;       // null means no condition
!     Expression            havingCondition;      // null means none
!     Expression[]          exprColumns;          // 'result', 'group' and 'order' columns
!     int                   iResultLen;           // number of columns that are 'result'
!     int                   iGroupLen;            // number of columns that are 'group'
!     int                   iHavingIndex = -1;    // -1 means no having
!     int                   iOrderLen;            // number of columns that are 'order'
      int[]                 sortOrder;
      int[]                 sortDirection;
!     HsqlName              sIntoTable;           // null means not select..into
      int                   intoType = Table.MEMORY_TABLE;
!     boolean               isIntoTableQuoted;
!     boolean               isMainSelect;         // false if this is appended in a union chain
!     Select[]              unionArray;           // only set in the first Select in a union chain
!     int                   unionMaxDepth;        // max unionDepth in chain
!     Select                unionSelect;          // null means no union select
      int                   unionType;
      int                   unionDepth;
      static final int      NOUNION   = 0,
--- 101,121 ----
      private HashSet       groupColumnNames;
      TableFilter[]         tFilter;
      Expression            limitCondition;
!     Expression            queryCondition;     // null means no condition
!     Expression            havingCondition;    // null means none
!     Expression[]          exprColumns;        // 'result', 'group' and 'order' columns
!     int                   iResultLen;         // number of columns that are 'result'
!     int                   iGroupLen;          // number of columns that are 'group'
!     int                   iHavingLen;         // number of columns that are 'group'
!     int                   iOrderLen;          // number of columns that are 'order'
      int[]                 sortOrder;
      int[]                 sortDirection;
!     boolean               sortUnion;          // if true, sort the result of the full union
!     HsqlName              sIntoTable;         // null means not select..into
      int                   intoType = Table.MEMORY_TABLE;
!     Select[]              unionArray;         // only set in the first Select in a union chain
!     int                   unionMaxDepth;      // max unionDepth in chain
!     Select                unionSelect;        // null means no union select
      int                   unionType;
      int                   unionDepth;
      static final int      NOUNION   = 0,
***************
*** 124,131 ****
                            UNIONALL  = 2,
                            INTERSECT = 3,
                            EXCEPT    = 4;
!     private int           limitStart;           // set only by the LIMIT keyword
!     private int           limitCount;           // set only by the LIMIT keyword
      Result.ResultMetaData resultMetaData;
  
      /**
--- 123,131 ----
                            UNIONALL  = 2,
                            INTERSECT = 3,
                            EXCEPT    = 4;
!     private int           limitStart;         // set only by the LIMIT keyword
!     private int           limitCount;         // set only by the LIMIT keyword
!     private boolean       simpleLimit;        // true if maxrows can be uses as is
      Result.ResultMetaData resultMetaData;
  
      /**
***************
*** 156,166 ****
       *
       * @throws HsqlException
       */
!     void resolve() throws HsqlException {
  
          resolveTables();
!         resolveTypes();
          setFilterConditions();
      }
  
      /**
--- 156,167 ----
       *
       * @throws HsqlException
       */
!     void resolve(Database database) throws HsqlException {
  
          resolveTables();
!         resolveTypes(database);
          setFilterConditions();
+         setLimitCounts();
      }
  
      /**
***************
*** 183,198 ****
       *
       * @throws HsqlException
       */
!     void resolveTypes() throws HsqlException {
  
          int len = exprColumns.length;
  
          for (int i = 0; i < len; i++) {
!             exprColumns[i].resolveTypes();
          }
  
          if (queryCondition != null) {
!             queryCondition.resolveTypes();
          }
      }
  
--- 184,199 ----
       *
       * @throws HsqlException
       */
!     void resolveTypes(Database database) throws HsqlException {
  
          int len = exprColumns.length;
  
          for (int i = 0; i < len; i++) {
!             exprColumns[i].resolveTypes(database);
          }
  
          if (queryCondition != null) {
!             queryCondition.resolveTypes(database);
          }
      }
  
***************
*** 292,298 ****
       */
      Object getValue(Session session, int type) throws HsqlException {
  
!         resolve();
  
          Result r    = getResult(session, 2);    // 2 records are (already) too much
          int    size = r.getSize();
--- 293,299 ----
       */
      Object getValue(Session session, int type) throws HsqlException {
  
!         resolve(session.database);
  
          Result r    = getResult(session, 2);    // 2 records are (already) too much
          int    size = r.getSize();
***************
*** 306,312 ****
                                                    type);
          }
  
!         HsqlException e = Trace.error(Trace.SINGLE_VALUE_EXPECTED);
  
          if (size == 0 && len == 1) {
              throw new HsqlInternalException(e);
--- 307,314 ----
                                                    type);
          }
  
!         HsqlException e =
!             Trace.error(Trace.CARDINALITY_VIOLATION_NO_SUBCLASS);
  
          if (size == 0 && len == 1) {
              throw new HsqlInternalException(e);
***************
*** 319,327 ****
       * Prepares rResult having structure compatible with
       * internally building the set of rows returned from getResult().
       */
!     void prepareResult() throws HsqlException {
  
!         resolveAll(true);
  
          if (iGroupLen > 0) {    // has been set in Parser
              isGrouped        = true;
--- 321,329 ----
       * Prepares rResult having structure compatible with
       * internally building the set of rows returned from getResult().
       */
!     void prepareResult(Database database) throws HsqlException {
  
!         resolveAll(database, true);
  
          if (iGroupLen > 0) {    // has been set in Parser
              isGrouped        = true;
***************
*** 341,348 ****
          // tony_lai@users having
          int groupByStart = iResultLen;
          int groupByEnd   = groupByStart + iGroupLen;
!         int orderByStart = iHavingIndex >= 0 ? (iHavingIndex + 1)
!                                              : groupByEnd;
          int orderByEnd   = orderByStart + iOrderLen;
  
          for (int i = 0; i < len; i++) {
--- 343,349 ----
          // tony_lai@users having
          int groupByStart = iResultLen;
          int groupByEnd   = groupByStart + iGroupLen;
!         int orderByStart = groupByEnd + iHavingLen;
          int orderByEnd   = orderByStart + iOrderLen;
  
          for (int i = 0; i < len; i++) {
***************
*** 356,372 ****
                  isAggregated = true;
              }
  
!             if (!(i < groupByStart || i >= groupByEnd
!                     || exprColumns[i].canBeInGroupBy())) {
                  Trace.error(Trace.INVALID_GROUP_BY, exprColumns[i]);
              }
  
!             if (!(i != iHavingIndex || exprColumns[i].isConditional())) {
                  Trace.error(Trace.INVALID_HAVING, exprColumns[i]);
              }
  
!             if (!(i < orderByStart) || i >= orderByEnd
!                     || exprColumns[i].canBeInOrderBy()) {
                  Trace.error(Trace.INVALID_ORDER_BY, exprColumns[i]);
              }
  
--- 357,374 ----
                  isAggregated = true;
              }
  
!             if (i >= groupByStart && i < groupByEnd
!                     &&!exprColumns[i].canBeInGroupBy()) {
                  Trace.error(Trace.INVALID_GROUP_BY, exprColumns[i]);
              }
  
!             if (i >= groupByEnd && i < groupByEnd + iHavingLen
!                     &&!exprColumns[i].isConditional()) {
                  Trace.error(Trace.INVALID_HAVING, exprColumns[i]);
              }
  
!             if (i >= orderByStart && i < orderByEnd
!                     &&!exprColumns[i].canBeInOrderBy()) {
                  Trace.error(Trace.INVALID_ORDER_BY, exprColumns[i]);
              }
  
***************
*** 387,411 ****
          }
  
          checkAggregateOrGroupByColumns(0, iResultLen);
! 
!         if (iHavingIndex >= 0) {
!             checkAggregateOrGroupByColumns(iHavingIndex, iHavingIndex + 1);
!         }
! 
          checkAggregateOrGroupByColumns(orderByStart, orderByEnd);
- 
-         /**
-          * @todo - this test is too strict and disallows functions in ORDER BY
-          * clause
-          */
-         if (isDistinctSelect) {
-             for (int i = orderByStart; i < orderByEnd; i++) {
-                 Trace.check(isSimilarIn(exprColumns[i], 0, iResultLen),
-                             Trace.INVALID_ORDER_BY_IN_DISTINCT_SELECT,
-                             exprColumns[i]);
-             }
-         }
- 
          prepareSort();
      }
  
--- 389,396 ----
          }
  
          checkAggregateOrGroupByColumns(0, iResultLen);
!         checkAggregateOrGroupByColumns(groupByEnd, orderByStart);
          checkAggregateOrGroupByColumns(orderByStart, orderByEnd);
          prepareSort();
      }
  
***************
*** 443,450 ****
          }
      }
  
- // fredt@users 20020130 - patch 471710 by fredt - LIMIT rewritten
- 
      /**
       * For SELECT LIMIT n m ....
       * finds cases where the result does not have to be fully built and
--- 428,433 ----
***************
*** 453,459 ****
       * not to individual SELECT statements in the set.
       *
       */
!     private int getLimitCount(int maxrows) throws HsqlException {
  
          limitStart = limitCondition == null ? 0
                                              : ((Integer) limitCondition
--- 436,442 ----
       * not to individual SELECT statements in the set.
       *
       */
!     private void setLimitCounts() throws HsqlException {
  
          limitStart = limitCondition == null ? 0
                                              : ((Integer) limitCondition
***************
*** 463,487 ****
                                              : ((Integer) limitCondition
                                              .getArg2().getValue(null))
                                                  .intValue();
  
          if (maxrows == 0) {
!             maxrows = limitCount;
!         } else if (limitCount == 0) {
!             limitCount = maxrows;
!         } else {
!             maxrows = limitCount = (maxrows > limitCount) ? limitCount
!                                                           : maxrows;
          }
  
!         boolean issimplemaxrows = false;
! 
!         if (maxrows != 0 && isDistinctSelect == false && isGrouped == false
!                 && unionSelect == null && iOrderLen == 0) {
!             issimplemaxrows = true;
          }
  
!         return issimplemaxrows ? limitStart + maxrows
!                                : Integer.MAX_VALUE;
      }
  
      /**
--- 446,475 ----
                                              : ((Integer) limitCondition
                                              .getArg2().getValue(null))
                                                  .intValue();
+         simpleLimit = (isDistinctSelect == false && isGrouped == false
+                        && unionSelect == null && iOrderLen == 0);
+     }
+ 
+     /**
+      * For SELECT LIMIT n m ....
+      * finds cases where the result does not have to be fully built and
+      * returns and adjusted maxrows with LIMIT params.
+      * LIMIT applies only to the result of UNION and other set operations,
+      * not to individual SELECT statements in the set.
+      *
+      */
+     private int getLimitCount(int maxrows) throws HsqlException {
  
          if (maxrows == 0) {
!             return limitCount;
          }
  
!         if (limitCount == 0) {
!             return maxrows;
          }
  
!         return (maxrows > limitCount) ? limitCount
!                                       : maxrows;
      }
  
      /**
***************
*** 496,514 ****
  
          Result r;
  
-         maxrows = getLimitCount(maxrows);
- 
          if (unionType == NOUNION) {
              r = getSingleResult(session, maxrows);
          } else {
              r = getResultMain(session);
-         }
  
!         sortResult(r);
  
          // fredt - now there is no need for the sort and group columns
          r.setColumnCount(iResultLen);
-         r.trimResult(limitStart, limitCount);
  
          return r;
      }
--- 484,504 ----
  
          Result r;
  
          if (unionType == NOUNION) {
              r = getSingleResult(session, maxrows);
          } else {
              r = getResultMain(session);
  
!             if (sortUnion) {
!                 int newlimitcount = getLimitCount(maxrows);
! 
!                 sortResult(session, r);
!                 r.trimResult(limitStart, newlimitcount);
!             }
!         }
  
          // fredt - now there is no need for the sort and group columns
          r.setColumnCount(iResultLen);
  
          return r;
      }
***************
*** 551,557 ****
                              break;
                          }
  
!                         unionArray[i].mergeResults(unionResults[i],
                                                     unionResults[nextIndex]);
  
                          unionResults[nextIndex] = unionResults[i];
--- 541,547 ----
                              break;
                          }
  
!                         unionArray[i].mergeResults(session, unionResults[i],
                                                     unionResults[nextIndex]);
  
                          unionResults[nextIndex] = unionResults[i];
***************
*** 568,581 ****
       * Merges the second result into the first using the unionMode
       * set operation.
       */
!     private void mergeResults(Result first,
                                Result second) throws HsqlException {
  
          switch (unionType) {
  
              case UNION :
                  first.append(second);
!                 first.removeDuplicates(iResultLen);
                  break;
  
              case UNIONALL :
--- 558,571 ----
       * Merges the second result into the first using the unionMode
       * set operation.
       */
!     private void mergeResults(Session session, Result first,
                                Result second) throws HsqlException {
  
          switch (unionType) {
  
              case UNION :
                  first.append(second);
!                 first.removeDuplicates(session, iResultLen);
                  break;
  
              case UNIONALL :
***************
*** 583,593 ****
                  break;
  
              case INTERSECT :
!                 first.removeDifferent(second, iResultLen);
                  break;
  
              case EXCEPT :
!                 first.removeSecond(second, iResultLen);
                  break;
          }
      }
--- 573,583 ----
                  break;
  
              case INTERSECT :
!                 first.removeDifferent(session, second, iResultLen);
                  break;
  
              case EXCEPT :
!                 first.removeSecond(session, second, iResultLen);
                  break;
          }
      }
***************
*** 596,610 ****
                                     int maxrows) throws HsqlException {
  
          if (resultMetaData == null) {
!             prepareResult();
          }
  
          Result r = buildResult(maxrows, session);
  
          // the result is perhaps wider (due to group and order by)
          // so use the visible columns to remove duplicates
          if (isDistinctSelect) {
!             r.removeDuplicates(iResultLen);
          }
  
          return r;
--- 586,611 ----
                                     int maxrows) throws HsqlException {
  
          if (resultMetaData == null) {
!             prepareResult(session.database);
          }
  
+         int newlimitcount = getLimitCount(maxrows);
+ 
+         maxrows = newlimitcount != 0 && simpleLimit
+                   ? limitStart + newlimitcount
+                   : Integer.MAX_VALUE;
+ 
          Result r = buildResult(maxrows, session);
  
          // the result is perhaps wider (due to group and order by)
          // so use the visible columns to remove duplicates
          if (isDistinctSelect) {
!             r.removeDuplicates(session, iResultLen);
!         }
! 
!         if (!sortUnion) {
!             sortResult(session, r);
!             r.trimResult(limitStart, newlimitcount);
          }
  
          return r;
***************
*** 619,640 ****
          sortOrder     = new int[iOrderLen];
          sortDirection = new int[iOrderLen];
  
!         int startCol;
! 
!         if (iHavingIndex > 0) {
!             startCol = iHavingIndex + 1;
!         } else {
!             startCol = iResultLen + (isGrouped ? iGroupLen
!                                                : 0);
!         }
  
          for (int i = startCol, j = 0; j < iOrderLen; i++, j++) {
              int colindex = i;
  
              // fredt - when a union, use the visible select columns for sort comparison
              // also whenever a column alias is used
!             if (exprColumns[i].orderColumnIndex != -1) {
!                 colindex = exprColumns[i].orderColumnIndex;
              }
  
              sortOrder[j]     = colindex;
--- 620,634 ----
          sortOrder     = new int[iOrderLen];
          sortDirection = new int[iOrderLen];
  
!         int startCol = iResultLen + iGroupLen + iHavingLen;
  
          for (int i = startCol, j = 0; j < iOrderLen; i++, j++) {
              int colindex = i;
  
              // fredt - when a union, use the visible select columns for sort comparison
              // also whenever a column alias is used
!             if (exprColumns[i].joinedTableColumnIndex != -1) {
!                 colindex = exprColumns[i].joinedTableColumnIndex;
              }
  
              sortOrder[j]     = colindex;
***************
*** 643,655 ****
          }
      }
  
!     private void sortResult(Result r) throws HsqlException {
  
          if (iOrderLen == 0) {
              return;
          }
  
!         r.sortResult(sortOrder, sortDirection);
      }
  
      /**
--- 637,649 ----
          }
      }
  
!     private void sortResult(Session session, Result r) throws HsqlException {
  
          if (iOrderLen == 0) {
              return;
          }
  
!         r.sortResult(session, sortOrder, sortDirection);
      }
  
      /**
***************
*** 868,879 ****
                  }
              }
  
!             if (iHavingIndex >= 0) {
  
                  // The test value, either aggregate or not, is set already.
                  // Removes the row that does not satisfy the HAVING
                  // condition.
!                 if (!((Boolean) row[iHavingIndex]).booleanValue()) {
                      it.remove();
                  }
              }
--- 862,873 ----
                  }
              }
  
!             if (iHavingLen > 0) {
  
                  // The test value, either aggregate or not, is set already.
                  // Removes the row that does not satisfy the HAVING
                  // condition.
!                 if (!Boolean.TRUE.equals(row[iResultLen + iGroupLen])) {
                      it.remove();
                  }
              }
***************
*** 945,952 ****
          // if has HAVING
          sb.append(' ').append(Token.T_HAVING).append(' ');
  
!         for (int i = iHavingIndex; i < iHavingIndex + exprColumns.length;
!                 i++) {
              sb.append(exprColumns[i].getDDL());
  
              if (i < iResultLen + iGroupLen - 1) {
--- 939,946 ----
          // if has HAVING
          sb.append(' ').append(Token.T_HAVING).append(' ');
  
!         for (int i = iResultLen + iGroupLen;
!                 i < iResultLen + iGroupLen + iHavingLen; i++) {
              sb.append(exprColumns[i].getDDL());
  
              if (i < iResultLen + iGroupLen - 1) {
***************
*** 978,985 ****
  
          // if has ORDER BY
          int groupByEnd   = iResultLen + iGroupLen;
!         int orderByStart = iHavingIndex >= 0 ? (iHavingIndex + 1)
!                                              : groupByEnd;
          int orderByEnd   = orderByStart + iOrderLen;
  
          sb.append(' ').append(Token.T_ORDER).append(Token.T_BY).append(' ');
--- 972,978 ----
  
          // if has ORDER BY
          int groupByEnd   = iResultLen + iGroupLen;
!         int orderByStart = groupByEnd + iHavingLen;
          int orderByEnd   = orderByStart + iOrderLen;
  
          sb.append(' ').append(Token.T_ORDER).append(Token.T_BY).append(' ');
***************
*** 997,1003 ****
  
      boolean isResolved = false;
  
!     boolean resolveAll(boolean check) throws HsqlException {
  
          boolean result = true;
  
--- 990,997 ----
  
      boolean isResolved = false;
  
!     boolean resolveAll(Database database,
!                        boolean check) throws HsqlException {
  
          boolean result = true;
  
***************
*** 1005,1011 ****
              return true;
          }
  
!         resolve();
  
          result = result && checkResolved(check);
  
--- 999,1005 ----
              return true;
          }
  
!         resolve(database);
  
          result = result && checkResolved(check);
  
***************
*** 1014,1020 ****
                  throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH);
              }
  
!             unionSelect.resolveAll(check);
          }
  
          isResolved = result;
--- 1008,1014 ----
                  throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH);
              }
  
!             unionSelect.resolveAll(database, check);
          }
  
          isResolved = result;
*** misc/hsqldb/src/org/hsqldb/ServerConnection.java	Wed Mar  2 14:50:55 2005
--- misc/build/hsqldb/src/org/hsqldb/ServerConnection.java	Thu Mar 31 10:35:27 2005
***************
*** 85,91 ****
   *  All ServerConnection objects are listed in a Set in server
   *  and removed by this class when closed.<p>
   *
!  *  When the datbase or server is shutdown, the signalClose() method is called
   *  for all current ServerConnection instances. This will call the private
   *  close() method unless the ServerConnection thread itself has caused the
   *  shutdown. In this case, the keepAlive flag is set to false, allowing the
--- 85,91 ----
   *  All ServerConnection objects are listed in a Set in server
   *  and removed by this class when closed.<p>
   *
!  *  When the database or server is shutdown, the signalClose() method is called
   *  for all current ServerConnection instances. This will call the private
   *  close() method unless the ServerConnection thread itself has caused the
   *  shutdown. In this case, the keepAlive flag is set to false, allowing the
***************
*** 93,106 ****
   *  the client.
   *  (fredt@users)<p>
   *
!  * @version 1.7.2
   */
  class ServerConnection implements Runnable {
  
      boolean                      keepAlive;
      private String               user;
      int                          dbID;
!     private Session              session;
      private Socket               socket;
      private Server               server;
      private DataInputStream      dataInput;
--- 93,107 ----
   *  the client.
   *  (fredt@users)<p>
   *
!  * @version 1.8.0
   */
  class ServerConnection implements Runnable {
  
      boolean                      keepAlive;
      private String               user;
+     private String               password;
      int                          dbID;
!     private volatile Session     session;
      private Socket               socket;
      private Server               server;
      private DataInputStream      dataInput;
***************
*** 191,198 ****
                  int dbIndex = ArrayUtil.find(server.dbAlias,
                                               resultIn.subSubString);
  
!                 dbID = server.dbID[dbIndex];
!                 user = resultIn.getMainString();
  
                  if (!server.isSilent()) {
                      server.printWithThread(mThread
--- 192,200 ----
                  int dbIndex = ArrayUtil.find(server.dbAlias,
                                               resultIn.subSubString);
  
!                 dbID     = server.dbID[dbIndex];
!                 user     = resultIn.getMainString();
!                 password = resultIn.getSubString();
  
                  if (!server.isSilent()) {
                      server.printWithThread(mThread
***************
*** 240,246 ****
  
                      server.printRequest(mThread, resultIn);
  
!                     Result resultOut = session.execute(resultIn);
  
                      Result.write(resultOut, rowOut, dataOutput);
                      rowOut.setBuffer(mainBuffer);
--- 242,254 ----
  
                      server.printRequest(mThread, resultIn);
  
!                     Result resultOut;
! 
!                     if (resultIn.mode == ResultConstants.HSQLRESETSESSION) {
!                         resultOut = resetSession();
!                     } else {
!                         resultOut = session.execute(resultIn);
!                     }
  
                      Result.write(resultOut, rowOut, dataOutput);
                      rowOut.setBuffer(mainBuffer);
***************
*** 261,266 ****
--- 269,302 ----
      }
  
      /**
+      * Used by pooled connections to close the existing SQL session and open
+      * a new one.
+      */
+     private Result resetSession() {
+ 
+         Result resultOut;
+ 
+         if (!server.isSilent()) {
+             server.printWithThread(mThread + ":trying to connect user "
+                                    + user);
+         }
+ 
+         try {
+             session.close();
+ 
+             session = DatabaseManager.newSession(dbID, user, password);
+             resultOut            = new Result(ResultConstants.UPDATECOUNT);
+             resultOut.databaseID = session.getDatabase().databaseID;
+             resultOut.sessionID  = session.getId();
+         } catch (HsqlException e) {
+             session   = null;
+             resultOut = new Result(e, null);
+         }
+ 
+         return resultOut;
+     }
+ 
+     /**
       * Retrieves the thread name to be used  when
       * this object is the Runnable object of a Thread.
       *
*** misc/hsqldb/src/org/hsqldb/Session.java	Wed Mar  2 14:50:55 2005
--- misc/build/hsqldb/src/org/hsqldb/Session.java	Thu Mar 31 10:35:27 2005
***************
*** 107,115 ****
      private volatile boolean isAutoCommit;
      private volatile boolean isReadOnly;
      private volatile boolean isClosed;
  
      //
!     private Database       database;
      private User           user;
      HsqlArrayList          transactionList;
      private boolean        isNestedTransaction;
--- 107,116 ----
      private volatile boolean isAutoCommit;
      private volatile boolean isReadOnly;
      private volatile boolean isClosed;
+     int                      isolation;
  
      //
!     Database               database;
      private User           user;
      HsqlArrayList          transactionList;
      private boolean        isNestedTransaction;
***************
*** 118,124 ****
      private int            sessionMaxRows;
      private Number         lastIdentity = ValuePool.getInt(0);
      private final int      sessionId;
!     private HashMappedList savepoints;
      private boolean        script;
      private jdbcConnection intConnection;
      private Tokenizer      tokenizer;
--- 119,125 ----
      private int            sessionMaxRows;
      private Number         lastIdentity = ValuePool.getInt(0);
      private final int      sessionId;
!     HashMappedList         savepoints;
      private boolean        script;
      private jdbcConnection intConnection;
      private Tokenizer      tokenizer;
***************
*** 214,219 ****
--- 215,228 ----
          return isClosed;
      }
  
+     public void setIsolation(int level) throws HsqlException {
+         isolation = level;
+     }
+ 
+     public int getIsolation() throws HsqlException {
+         return isolation;
+     }
+ 
      /**
       * Setter for iLastIdentity attribute.
       *
***************
*** 349,354 ****
--- 358,364 ----
              Transaction t = new Transaction(true, table, row, sessionSCN);
  
              transactionList.add(t);
+             database.txManager.addTransaction(this, t);
          }
      }
  
***************
*** 365,370 ****
--- 375,381 ----
              Transaction t = new Transaction(false, table, row, sessionSCN);
  
              transactionList.add(t);
+             database.txManager.addTransaction(this, t);
          }
      }
  
***************
*** 410,419 ****
                  try {
                      database.logger.writeCommitStatement(this);
                  } catch (HsqlException e) {}
- 
-                 transactionList.clear();
-                 savepoints.clear();
              }
          }
      }
  
--- 421,429 ----
                  try {
                      database.logger.writeCommitStatement(this);
                  } catch (HsqlException e) {}
              }
+ 
+             database.txManager.commit(this);
          }
      }
  
***************
*** 429,455 ****
          }
  
          synchronized (database) {
!             int i = transactionList.size();
! 
!             while (i-- > 0) {
!                 Transaction t = (Transaction) transactionList.get(i);
! 
!                 t.rollback(this, false);
!             }
! 
!             if (!transactionList.isEmpty()) {
                  try {
                      database.logger.writeToLog(this, Token.T_ROLLBACK);
                  } catch (HsqlException e) {}
- 
-                 transactionList.clear();
              }
  
!             savepoints.clear();
          }
      }
  
      /**
       *  Implements a transaction SAVEPOINT. A new SAVEPOINT with the
       *  name of an existing one replaces the old SAVEPOINT.
       *
--- 439,462 ----
          }
  
          synchronized (database) {
!             if (transactionList.size() != 0) {
                  try {
                      database.logger.writeToLog(this, Token.T_ROLLBACK);
                  } catch (HsqlException e) {}
              }
  
!             database.txManager.rollback(this);
          }
      }
  
      /**
+      * No-op in this implementation
+      */
+     public void resetSession() throws HsqlException {
+         throw new HsqlException("","",0);
+     }
+ 
+     /**
       *  Implements a transaction SAVEPOINT. A new SAVEPOINT with the
       *  name of an existing one replaces the old SAVEPOINT.
       *
***************
*** 475,490 ****
       */
      void rollbackToSavepoint(String name) throws HsqlException {
  
!         int index = savepoints.getIndex(name);
! 
!         Trace.check(index >= 0, Trace.SAVEPOINT_NOT_FOUND, name);
! 
!         Integer oi = (Integer) savepoints.get(index);
! 
!         index = oi.intValue();
! 
!         rollbackToSavepoint(index, false);
!         releaseSavepoint(name);
  
          try {
              database.logger.writeToLog(this,
--- 482,490 ----
       */
      void rollbackToSavepoint(String name) throws HsqlException {
  
!         if (isClosed) {
!             return;
!         }
  
          try {
              database.logger.writeToLog(this,
***************
*** 492,511 ****
                                         + " " + Token.T_SAVEPOINT + " "
                                         + name);
          } catch (HsqlException e) {}
-     }
- 
-     private void rollbackToSavepoint(int index,
-                                      boolean log) throws HsqlException {
  
!         int i = transactionList.size() - 1;
! 
!         for (; i >= index; i--) {
!             Transaction t = (Transaction) transactionList.get(i);
! 
!             t.rollback(this, log);
!         }
! 
!         transactionList.setSize(index);
      }
  
      /**
--- 492,499 ----
                                         + " " + Token.T_SAVEPOINT + " "
                                         + name);
          } catch (HsqlException e) {}
  
!         database.txManager.rollbackSavepoint(this, name);
      }
  
      /**
***************
*** 551,557 ****
          Trace.doAssert(isNestedTransaction, "endNestedTransaction");
  
          if (rollback) {
!             rollbackToSavepoint(nestedOldTransIndex, true);
          }
  
          // reset after the rollback
--- 539,546 ----
          Trace.doAssert(isNestedTransaction, "endNestedTransaction");
  
          if (rollback) {
!             database.txManager.rollbackTransactions(this,
!                     nestedOldTransIndex, true);
          }
  
          // reset after the rollback
***************
*** 1290,1318 ****
      static final int INFO_DATABASE            = 0;
      static final int INFO_USER                = 1;
      static final int INFO_SESSION_ID          = 2;
!     static final int INFO_IDENTITY            = 3;
      static final int INFO_AUTOCOMMIT          = 4;
      static final int INFO_DATABASE_READONLY   = 5;
      static final int INFO_CONNECTION_READONLY = 6;
  
      Result getAttributes() {
  
!         Result r = new Result(ResultConstants.DATA, 7);
! 
!         r.metaData.colNames = r.metaData.colLabels = r.metaData.tableNames =
!             new String[] {
!             "", "", "", "", "", "", ""
!         };
!         r.metaData.colTypes = new int[] {
!             Types.VARCHAR, Types.VARCHAR, Types.INTEGER,
!             lastIdentity instanceof Long ? Types.BIGINT
!                                          : Types.INTEGER, Types.BOOLEAN,
!             Types.BOOLEAN, Types.BOOLEAN
!         };
! 
          Object[] row = new Object[] {
              database.getURI(), getUsername(), ValuePool.getInt(sessionId),
!             lastIdentity, ValuePool.getBoolean(isAutoCommit),
              ValuePool.getBoolean(database.databaseReadOnly),
              ValuePool.getBoolean(isReadOnly)
          };
--- 1279,1295 ----
      static final int INFO_DATABASE            = 0;
      static final int INFO_USER                = 1;
      static final int INFO_SESSION_ID          = 2;
!     static final int INFO_ISOLATION           = 3;
      static final int INFO_AUTOCOMMIT          = 4;
      static final int INFO_DATABASE_READONLY   = 5;
      static final int INFO_CONNECTION_READONLY = 6;
  
      Result getAttributes() {
  
!         Result   r   = Result.newSessionAttributesResult();
          Object[] row = new Object[] {
              database.getURI(), getUsername(), ValuePool.getInt(sessionId),
!             ValuePool.getInt(isolation), ValuePool.getBoolean(isAutoCommit),
              ValuePool.getBoolean(database.databaseReadOnly),
              ValuePool.getBoolean(isReadOnly)
          };
*** misc/hsqldb/src/org/hsqldb/SessionInterface.java	Wed Mar  2 14:50:55 2005
--- misc/build/hsqldb/src/org/hsqldb/SessionInterface.java	Thu Mar 31 10:35:27 2005
***************
*** 56,64 ****
--- 56,70 ----
  
      void setAutoCommit(boolean autoCommit) throws HsqlException;
  
+     void setIsolation(int level) throws HsqlException;
+ 
+     int getIsolation() throws HsqlException;
+ 
      void commit() throws HsqlException;
  
      void rollback() throws HsqlException;
  
      int getId();
+ 
+     void resetSession() throws HsqlException;
  }
*** misc/hsqldb/src/org/hsqldb/SetFunction.java	Wed Mar  2 14:50:55 2005
--- misc/build/hsqldb/src/org/hsqldb/SetFunction.java	Thu Mar 31 10:35:27 2005
***************
*** 77,83 ****
          }
      }
  
!     void add(Object item) throws HsqlException {
  
          if (item == null) {
              hasNull = true;
--- 77,83 ----
          }
      }
  
!     void add(Session session, Object item) throws HsqlException {
  
          if (item == null) {
              hasNull = true;
***************
*** 141,147 ****
                      return;
                  }
  
!                 if (Column.compare(currentValue, item, type) > 0) {
                      currentValue = item;
                  }
  
--- 141,149 ----
                      return;
                  }
  
!                 if (Column.compare(
!                         session.database.collation, currentValue, item,
!                         type) > 0) {
                      currentValue = item;
                  }
  
***************
*** 154,160 ****
                      return;
                  }
  
!                 if (Column.compare(currentValue, item, type) < 0) {
                      currentValue = item;
                  }
  
--- 156,164 ----
                      return;
                  }
  
!                 if (Column.compare(
!                         session.database.collation, currentValue, item,
!                         type) < 0) {
                      currentValue = item;
                  }
  
*** misc/hsqldb/src/org/hsqldb/SubQuery.java	Wed Mar  2 14:50:55 2005
--- misc/build/hsqldb/src/org/hsqldb/SubQuery.java	Thu Mar 31 10:35:27 2005
***************
*** 49,55 ****
      boolean hasParams;
      boolean isResolved;
      boolean isExistsPredicate;
!     boolean isInPredicate;
      Select  select;
      Table   table;
      View    view;
--- 49,55 ----
      boolean hasParams;
      boolean isResolved;
      boolean isExistsPredicate;
!     boolean uniqueRows;
      Select  select;
      Table   table;
      View    view;
*** misc/hsqldb/src/org/hsqldb/Table.java	Wed Mar  2 15:11:13 2005
--- misc/build/hsqldb/src/org/hsqldb/Table.java	Thu Mar 31 10:35:27 2005
***************
*** 67,74 ****
  package org.hsqldb;
  
  import java.io.IOException;
- import java.math.BigDecimal;
- import java.math.BigInteger;
  
  import org.hsqldb.HsqlNameManager.HsqlName;
  import org.hsqldb.index.RowIterator;
--- 67,72 ----
***************
*** 129,137 ****
  // boucherb@users - for future implementation of SQL standard INFORMATION_SCHEMA
      static final int SYSTEM_VIEW = 8;
  
-     // name of the column added to tables without primary key
-     static final String DEFAULT_PK = "";
- 
      // main properties
  // boucherb@users - access changed in support of metadata 1.7.2
      public HashMappedList columnList;                 // columns in table
--- 127,132 ----
***************
*** 573,578 ****
--- 568,577 ----
          return tableName;
      }
  
+     public int getId() {
+         return tableName.hashCode();
+     }
+ 
      /**
       * Changes table name. Used by 'alter table rename to'.
       * Essential to use the existing HsqlName as this is is referenced by
***************
*** 640,666 ****
  // fredt@users 20020405 - patch 1.7.0 by fredt - DROP and CREATE INDEX bug
  
      /**
-      * DROP INDEX and CREATE INDEX on non empty tables both recreate the table
-      * and the data to reflect the new indexing structure. The new structure
-      * should be reflected in the DDL script, otherwise if a
-      * SHUTDOWN IMMEDIATELY occures, the following will happen:<br>
-      *
-      * <ul>
-      * <li>If the table is cached, the index roots will be different from what
-      *     is specified in SET INDEX ROOTS. <p>
-      *
-      * <li>If the table is memory, the old index will be used until the script
-      *     reaches drop index etc. and data is recreated again. <p>
-      *
-      * <ul>
-      *
-      * The fix avoids scripting the row insert and delete ops. <p>
-      *
       * Constraints that need removing are removed outside this method.<br>
!      * withoutindex is the name of an index to be removed <br>
!      * adjust {-1 | 0 | +1} indicates if a column {removed | no change | added}
       */
!     Table moveDefinition(String withoutindex, Column newcolumn, int colindex,
                           int adjust) throws HsqlException {
  
          Table tn = duplicate();
--- 639,652 ----
  // fredt@users 20020405 - patch 1.7.0 by fredt - DROP and CREATE INDEX bug
  
      /**
       * Constraints that need removing are removed outside this method.<br>
!      * withoutindex is the name of an index to be removed, in which case
!      * no change is made to columns <br>
!      * When withoutindex is null,  adjust {-1 | 0 | +1} indicates if a
!      * column is {removed | replaced | added}
!      *
       */
!     Table moveDefinition(String withoutIndex, Column newColumn, int colIndex,
                           int adjust) throws HsqlException {
  
          Table tn = duplicate();
***************
*** 668,676 ****
          // loop beyond the end in order to be able to add a column to the end
          // of the list
          for (int i = 0; i < columnCount + 1; i++) {
!             if (i == colindex) {
!                 if (adjust > 0) {
!                     tn.addColumn(newcolumn);
                  } else if (adjust < 0) {
                      continue;
                  }
--- 654,668 ----
          // loop beyond the end in order to be able to add a column to the end
          // of the list
          for (int i = 0; i < columnCount + 1; i++) {
!             if (i == colIndex) {
!                 if (adjust == 0) {
!                     if (newColumn != null) {
!                         tn.addColumn(newColumn);
! 
!                         continue;
!                     }
!                 } else if (adjust > 0) {
!                     tn.addColumn(newColumn);
                  } else if (adjust < 0) {
                      continue;
                  }
***************
*** 689,698 ****
  
          if (primarykey != null) {
              int[] newpk = ArrayUtil.toAdjustedColumnArray(primarykey,
!                 colindex, adjust);
  
-             // fredt - we don't drop pk column
-             // although we _can_ drop single column pk wih no fk reference
              if (primarykey.length != newpk.length) {
                  throw Trace.error(Trace.DROP_PRIMARY_KEY);
              } else {
--- 681,688 ----
  
          if (primarykey != null) {
              int[] newpk = ArrayUtil.toAdjustedColumnArray(primarykey,
!                 colIndex, adjust);
  
              if (primarykey.length != newpk.length) {
                  throw Trace.error(Trace.DROP_PRIMARY_KEY);
              } else {
***************
*** 708,719 ****
          for (int i = 1; i < getIndexCount(); i++) {
              Index idx = getIndex(i);
  
!             if (withoutindex != null
!                     && idx.getName().name.equals(withoutindex)) {
                  continue;
              }
  
!             Index newidx = tn.createAdjustedIndex(idx, colindex, adjust);
  
              if (newidx == null) {
  
--- 698,709 ----
          for (int i = 1; i < getIndexCount(); i++) {
              Index idx = getIndex(i);
  
!             if (withoutIndex != null
!                     && idx.getName().name.equals(withoutIndex)) {
                  continue;
              }
  
!             Index newidx = tn.createAdjustedIndex(idx, colIndex, adjust);
  
              if (newidx == null) {
  
***************
*** 832,837 ****
--- 822,844 ----
      }
  
      /**
+      * Used for retype column. Checks whether column is in an FK or is
+      * referenced by an FK
+      */
+     void checkColumnInFKConstraint(String colname) throws HsqlException {
+ 
+         int colIndex = getColumnNr(colname);
+ 
+         for (int i = 0, size = constraintList.length; i < size; i++) {
+             Constraint c = constraintList[i];
+ 
+             if (c.hasColumn(colIndex)) {
+                 throw Trace.error(Trace.COLUMN_IS_REFERENCED, c.getName());
+             }
+         }
+     }
+ 
+     /**
       * Used for rename column.
       */
      private void renameColumnInCheckConstraints(String oldname,
***************
*** 1327,1341 ****
  
          // tony_lai@users 20020820 - patch 595099
          HsqlName name = pkName != null ? pkName
!                                        : makeSysPKName(this);
  
          createPrimaryIndex(columns, name);
          setBestRowIdentifiers();
      }
  
!     static HsqlName makeSysPKName(Table table) throws HsqlException {
!         return table.database.nameManager.newHsqlName("SYS_PK",
!                 table.tableName.name, table.tableName.isNameQuoted);
      }
  
      void createPrimaryIndex(int[] pkcols,
--- 1334,1350 ----
  
          // tony_lai@users 20020820 - patch 595099
          HsqlName name = pkName != null ? pkName
!                                        : makeSysPKName();
  
          createPrimaryIndex(columns, name);
          setBestRowIdentifiers();
      }
  
!     HsqlName makeSysPKName() throws HsqlException {
! 
!         return isTemp ? database.nameManager.newAutoName("PK")
!                       : database.nameManager.newHsqlName("SYS_PK",
!                       tableName.name, tableName.isNameQuoted);
      }
  
      void createPrimaryIndex(int[] pkcols,
***************
*** 1386,1392 ****
              constraint, forward);
          Index       newindex     = indexList[newindexNo];
          Index       primaryindex = getPrimaryIndex();
!         RowIterator it           = primaryindex.firstRow(null);
          int         rowCount     = 0;
          int         error        = 0;
  
--- 1395,1402 ----
              constraint, forward);
          Index       newindex     = indexList[newindexNo];
          Index       primaryindex = getPrimaryIndex();
!         Session     session      = database.sessionManager.getSysSession();
!         RowIterator it           = primaryindex.firstRow(session);
          int         rowCount     = 0;
          int         error        = 0;
  
***************
*** 1402,1408 ****
                  // count before inserting
                  rowCount++;
  
!                 newindex.insert(row, newindexNo);
              }
  
              return newindex;
--- 1412,1418 ----
                  // count before inserting
                  rowCount++;
  
!                 newindex.insert(session, row, newindexNo);
              }
  
              return newindex;
***************
*** 1414,1420 ****
  
          // backtrack on error
          // rowCount rows have been modified
!         it = primaryindex.firstRow(null);
  
          for (int i = 0; i < rowCount; i++) {
              Row  row      = it.next();
--- 1424,1430 ----
  
          // backtrack on error
          // rowCount rows have been modified
!         it = primaryindex.firstRow(session);
  
          for (int i = 0; i < rowCount; i++) {
              Row  row      = it.next();
***************
*** 1653,1662 ****
                    int adjust) throws HsqlException {
  
          Object colvalue = null;
  
!         if (adjust > 0) {
!             Column column = getColumn(colindex);
! 
              colvalue = column.getDefaultValue(session);
          }
  
--- 1663,1672 ----
                    int adjust) throws HsqlException {
  
          Object colvalue = null;
+         Column column   = null;
  
!         if (adjust >= 0 && colindex != -1) {
!             column   = getColumn(colindex);
              colvalue = column.getDefaultValue(session);
          }
  
***************
*** 1667,1679 ****
              Object[] o    = row.getData();
              Object[] data = getEmptyRowData();
  
              ArrayUtil.copyAdjustArray(o, data, colvalue, colindex, adjust);
              updateIdentityValue(data);
              enforceNullConstraints(data);
  
              Row newrow = newRow(data);
  
!             indexRow(newrow);
          }
  
          from.drop();
--- 1677,1696 ----
              Object[] o    = row.getData();
              Object[] data = getEmptyRowData();
  
+             if (adjust == 0 && colindex != -1) {
+                 colvalue = Column.convertObject(session, o[colindex],
+                                                 column.getType(),
+                                                 column.getSize(),
+                                                 column.getScale());
+             }
+ 
              ArrayUtil.copyAdjustArray(o, data, colvalue, colindex, adjust);
              updateIdentityValue(data);
              enforceNullConstraints(data);
  
              Row newrow = newRow(data);
  
!             indexRow(session, newrow);
          }
  
          from.drop();
***************
*** 1746,1752 ****
      void insertIntoTable(Session session,
                           Result result) throws HsqlException {
  
!         insert(result);
  
          if (isTemp || isText ||!database.logger.hasLog()) {
              return;
--- 1763,1769 ----
      void insertIntoTable(Session session,
                           Result result) throws HsqlException {
  
!         insertResult(session, result);
  
          if (isTemp || isText ||!database.logger.hasLog()) {
              return;
***************
*** 1772,1778 ****
          Row r = newRow(data);
  
          // this handles the UNIQUE constraints
!         indexRow(r);
  
          if (session != null) {
              session.addTransactionInsert(this, r);
--- 1789,1795 ----
          Row r = newRow(data);
  
          // this handles the UNIQUE constraints
!         indexRow(session, r);
  
          if (session != null) {
              session.addTransactionInsert(this, r);
***************
*** 1794,1800 ****
          Row r = newRow(data);
  
          updateIdentityValue(data);
!         indexRow(r);
  
          if (session != null) {
              session.addTransactionInsert(this, r);
--- 1811,1817 ----
          Row r = newRow(data);
  
          updateIdentityValue(data);
!         indexRow(session, r);
  
          if (session != null) {
              session.addTransactionInsert(this, r);
***************
*** 1811,1817 ****
  
          row = newRow(row.getData());
  
!         indexRow(row);
  
          if (log &&!isTemp &&!isText &&!isReadOnly) {
              database.logger.writeInsertStatement(session, this,
--- 1828,1834 ----
  
          row = newRow(row.getData());
  
!         indexRow(session, row);
  
          if (log &&!isTemp &&!isText &&!isReadOnly) {
              database.logger.writeInsertStatement(session, this,
***************
*** 1820,1835 ****
      }
  
      /**
!      * Used for subquery and system table inserts. No checks. No identity
       * columns.
       */
!     int insert(Result ins) throws HsqlException {
  
          Record ni    = ins.rRoot;
          int    count = 0;
  
          while (ni != null) {
!             insert(ni.data);
  
              ni = ni.next;
  
--- 1837,1873 ----
      }
  
      /**
!      * Used for system table inserts. No checks. No identity
!      * columns.
!      */
!     int insertSys(Result ins) throws HsqlException {
! 
!         Session session = database.sessionManager.getSysSession();
!         Record  ni      = ins.rRoot;
!         int     count   = 0;
! 
!         while (ni != null) {
!             insertData(session, ni.data);
! 
!             ni = ni.next;
! 
!             count++;
!         }
! 
!         return count;
!     }
! 
!     /**
!      * Used for subquery inserts. No checks. No identity
       * columns.
       */
!     int insertResult(Session session, Result ins) throws HsqlException {
  
          Record ni    = ins.rRoot;
          int    count = 0;
  
          while (ni != null) {
!             insertData(session, ni.data);
  
              ni = ni.next;
  
***************
*** 1845,1872 ****
       * the table when the .script file is read.
       */
      public void insertFromScript(Object[] data) throws HsqlException {
          updateIdentityValue(data);
!         insert(data);
      }
  
      /**
!      * Used by the methods above. To avoid unnecessary
!      * creation of arrays The Object[] for data in the Result rows is inserted
!      * into the table if it has the same length as table row data.
       */
!     public void insert(Object[] data) throws HsqlException {
  
!         if (data.length != columnCount) {
!             Object[] newdata = getEmptyRowData();
  
!             ArrayUtil.copyArray(data, newdata, columnCount);
  
!             data = newdata;
!         }
  
!         Row r = newRow(data);
  
!         indexRow(r);
      }
  
      /**
--- 1883,1915 ----
       * the table when the .script file is read.
       */
      public void insertFromScript(Object[] data) throws HsqlException {
+ 
+         Session session = database.sessionManager.getSysSession();
+ 
          updateIdentityValue(data);
!         insertData(session, data);
      }
  
      /**
!      * Used by the methods above.
       */
!     public void insertData(Session session,
!                            Object[] data) throws HsqlException {
  
!         Row r = newRow(data);
  
!         indexRow(session, r);
!     }
  
!     /**
!      * Used by the system tables
!      */
!     public void insertSys(Object[] data) throws HsqlException {
  
!         Session session = database.sessionManager.getSysSession();
!         Row     r       = newRow(data);
  
!         indexRow(session, r);
      }
  
      /**
***************
*** 1875,1886 ****
       */
      protected void insertNoChange(CachedRow row) throws HsqlException {
  
!         Object[] data = row.getData();
  
          updateIdentityValue(data);
          enforceFieldValueLimits(data, defaultColumnMap);
          enforceNullConstraints(data);
!         indexRow(row);
      }
  
      /**
--- 1918,1930 ----
       */
      protected void insertNoChange(CachedRow row) throws HsqlException {
  
!         Session  session = database.sessionManager.getSysSession();
!         Object[] data    = row.getData();
  
          updateIdentityValue(data);
          enforceFieldValueLimits(data, defaultColumnMap);
          enforceNullConstraints(data);
!         indexRow(session, row);
      }
  
      /**
***************
*** 2195,2201 ****
  
                  if (refrow == null || refrow.isDeleted()
                          || refindex.compareRowNonUnique(
!                             mdata, m_columns, refrow.getData()) != 0) {
                      break;
                  }
  
--- 2239,2246 ----
  
                  if (refrow == null || refrow.isDeleted()
                          || refindex.compareRowNonUnique(
!                             session, mdata, m_columns,
!                             refrow.getData()) != 0) {
                      break;
                  }
  
***************
*** 2400,2406 ****
                          refrow = refiterator.next()) {
                      if (refrow == null
                              || refindex.compareRowNonUnique(
!                                 orow.getData(), m_columns,
                                  refrow.getData()) != 0) {
                          break;
                      }
--- 2445,2451 ----
                          refrow = refiterator.next()) {
                      if (refrow == null
                              || refindex.compareRowNonUnique(
!                                 session, orow.getData(), m_columns,
                                  refrow.getData()) != 0) {
                          break;
                      }
***************
*** 2480,2495 ****
       * Merge the full triggered change with the updated row, or add to list.
       * Return false if changes conflict.
       */
!     static boolean mergeKeepUpdate(HashMappedList rowSet, int[] cols,
!                                    int[] colTypes, Row row,
                                     Object[] newData) throws HsqlException {
  
          Object[] data = (Object[]) rowSet.get(row);
  
          if (data != null) {
!             if (Index.compareRows(row
!                     .getData(), newData, cols, colTypes) != 0 && Index
!                         .compareRows(newData, data, cols, colTypes) != 0) {
                  return false;
              }
  
--- 2525,2542 ----
       * Merge the full triggered change with the updated row, or add to list.
       * Return false if changes conflict.
       */
!     static boolean mergeKeepUpdate(Session session, HashMappedList rowSet,
!                                    int[] cols, int[] colTypes, Row row,
                                     Object[] newData) throws HsqlException {
  
          Object[] data = (Object[]) rowSet.get(row);
  
          if (data != null) {
!             if (Index.compareRows(
!                     session, row
!                         .getData(), newData, cols, colTypes) != 0 && Index
!                             .compareRows(
!                                 session, newData, data, cols, colTypes) != 0) {
                  return false;
              }
  
***************
*** 2543,2548 ****
--- 2590,2606 ----
              }
          }
  
+         // check transactions
+         database.txManager.checkDelete(session, deleteList);
+ 
+         for (int i = 0; i < tUpdateList.size(); i++) {
+             Table          table      = (Table) tUpdateList.getKey(i);
+             HashMappedList updateList = (HashMappedList) tUpdateList.get(i);
+ 
+             database.txManager.checkDelete(session, updateList);
+         }
+ 
+         // perform delete
          fireAll(session, Trigger.DELETE_BEFORE);
  
          if (database.isReferentialIntegrity()) {
***************
*** 2652,2658 ****
                  }
  
                  if (Index.compareRows(
!                         row.getData(), data, defaultColumnMap,
                          colTypes) == 0) {
                      break;
                  }
--- 2710,2716 ----
                  }
  
                  if (Index.compareRows(
!                         session, row.getData(), data, defaultColumnMap,
                          colTypes) == 0) {
                      break;
                  }
***************
*** 2671,2684 ****
  
                  // reached end of range
                  if (bestIndex.compareRowNonUnique(
!                         data, bestIndex.getColumns(), rowdata) != 0) {
                      row = null;
  
                      break;
                  }
  
                  if (Index.compareRows(
!                         rowdata, data, defaultColumnMap, colTypes) == 0) {
                      break;
                  }
              }
--- 2729,2744 ----
  
                  // reached end of range
                  if (bestIndex.compareRowNonUnique(
!                         session, data, bestIndex.getColumns(),
!                         rowdata) != 0) {
                      row = null;
  
                      break;
                  }
  
                  if (Index.compareRows(
!                         session, rowdata, data, defaultColumnMap,
!                         colTypes) == 0) {
                      break;
                  }
              }
***************
*** 2688,2693 ****
--- 2748,2756 ----
              return;
          }
  
+         // not necessary for log deletes
+         database.txManager.checkDelete(session, row);
+ 
          for (int i = indexList.length - 1; i >= 0; i--) {
              Node node = row.getNode(i);
  
***************
*** 2708,2715 ****
      void deleteNoCheckRollback(Session session, Row row,
                                 boolean log) throws HsqlException {
  
-         // the orininal row may have been deleted by another transaction
-         // so we do not use it directly
          row = getIndex(0).findRow(session, row);
  
          for (int i = indexList.length - 1; i >= 0; i--) {
--- 2771,2776 ----
***************
*** 2798,2809 ****
                  Row      row  = (Row) triggeredList.getKey(i);
                  Object[] data = (Object[]) triggeredList.get(i);
  
!                 mergeKeepUpdate(updateList, cols, colTypes, row, data);
              }
  
              triggeredList.clear();
          }
  
          for (int i = 0; i < tUpdateList.size(); i++) {
              Table          table       = (Table) tUpdateList.getKey(i);
              HashMappedList updateListT = (HashMappedList) tUpdateList.get(i);
--- 2859,2882 ----
                  Row      row  = (Row) triggeredList.getKey(i);
                  Object[] data = (Object[]) triggeredList.get(i);
  
!                 mergeKeepUpdate(session, updateList, cols, colTypes, row,
!                                 data);
              }
  
              triggeredList.clear();
          }
  
+         // check transactions
+         for (int i = 0; i < tUpdateList.size(); i++) {
+             Table          table       = (Table) tUpdateList.getKey(i);
+             HashMappedList updateListT = (HashMappedList) tUpdateList.get(i);
+ 
+             database.txManager.checkDelete(session, updateListT);
+         }
+ 
+         database.txManager.checkDelete(session, updateList);
+ 
+         // update lists - main list last
          for (int i = 0; i < tUpdateList.size(); i++) {
              Table          table       = (Table) tUpdateList.getKey(i);
              HashMappedList updateListT = (HashMappedList) tUpdateList.get(i);
***************
*** 2812,2818 ****
              updateListT.clear();
          }
  
-         // update main list
          updateRowSet(session, updateList, cols, true);
          fireAll(session, Trigger.UPDATE_AFTER);
          path.clear();
--- 2885,2890 ----
***************
*** 3034,3050 ****
  
      void registerRow(CachedRow row) {}
  
      void removeRow(CachedRow row) throws HsqlException {
          rowStore.remove(row.getPos());
      }
  
!     void indexRow(Row row) throws HsqlException {
  
          int i = 0;
  
          try {
!             for (; i < getIndexCount(); i++) {
!                 indexList[i].insert(row, i);
              }
          } catch (HsqlException e) {
              Index   index        = indexList[i];
--- 3106,3124 ----
  
      void registerRow(CachedRow row) {}
  
+     /**
+      */
      void removeRow(CachedRow row) throws HsqlException {
          rowStore.remove(row.getPos());
      }
  
!     void indexRow(Session session, Row row) throws HsqlException {
  
          int i = 0;
  
          try {
!             for (; i < indexList.length; i++) {
!                 indexList[i].insert(session, row, i);
              }
          } catch (HsqlException e) {
              Index   index        = indexList[i];
***************
*** 3161,3169 ****
              return;
          }
  
          rowIdSequence = new NumberSequence(null, 0, 1, Types.BIGINT);
  
!         RowIterator it = rowIterator(null);
  
          while (it.hasNext()) {
              Row row = it.next();
--- 3235,3245 ----
              return;
          }
  
+         Session session = database.sessionManager.getSysSession();
+ 
          rowIdSequence = new NumberSequence(null, 0, 1, Types.BIGINT);
  
!         RowIterator it = rowIterator(session);
  
          while (it.hasNext()) {
              Row row = it.next();
*** misc/hsqldb/src/org/hsqldb/TableFilter.java	Wed Mar  2 14:50:56 2005
--- misc/build/hsqldb/src/org/hsqldb/TableFilter.java	Thu Mar 31 10:35:27 2005
***************
*** 160,173 ****
       * @param exprType an expression type code
       * @return
       */
!     static int toConditionType(int exprType) {
  
          switch (exprType) {
  
              case Expression.NOT_EQUAL :
              case Expression.LIKE :
-             case Expression.IN : {
                  return CONDITION_UNORDERED;
              }
              case Expression.IS_NULL :
              case Expression.EQUAL : {
--- 160,178 ----
       * @param exprType an expression type code
       * @return
       */
!     static int getConditionType(Expression e) {
! 
!         int exprType = e.getType();
  
          switch (exprType) {
  
              case Expression.NOT_EQUAL :
              case Expression.LIKE :
                  return CONDITION_UNORDERED;
+ 
+             case Expression.IN : {
+                 return e.isCorrelated ? CONDITION_NONE
+                                       : CONDITION_UNORDERED;
              }
              case Expression.IS_NULL :
              case Expression.EQUAL : {
***************
*** 328,334 ****
              return;
          }
  
!         int conditionType = toConditionType(type);
  
          if (conditionType == CONDITION_NONE) {
  
--- 333,347 ----
              return;
          }
  
!         if (type == Expression.OR && isOuterJoin && e.isInJoin
!                 && e.outerFilter == this) {
!             addAndCondition(e);
!             e.setTrue();
! 
!             return;
!         }
! 
!         int conditionType = getConditionType(e);
  
          if (conditionType == CONDITION_NONE) {
  
***************
*** 472,478 ****
                  Expression e = findFirstExpressions[i];
  
                  if (e != null) {
!                     data[i] = e.getValue(null, types[i]);
                  }
              }
  
--- 485,491 ----
                  Expression e = findFirstExpressions[i];
  
                  if (e != null) {
!                     data[i] = e.getValue(session, types[i]);
                  }
              }
  
*** misc/hsqldb/src/org/hsqldb/TableWorks.java	Wed Mar  2 14:50:56 2005
--- misc/build/hsqldb/src/org/hsqldb/TableWorks.java	Thu Mar 31 10:35:27 2005
***************
*** 33,38 ****
--- 33,39 ----
  
  import org.hsqldb.lib.ArrayUtil;
  import org.hsqldb.lib.HashSet;
+ import org.hsqldb.index.RowIterator;
  import org.hsqldb.HsqlNameManager.HsqlName;
  
  // fredt@users 20020520 - patch 1.7.0 - ALTER TABLE support
***************
*** 139,145 ****
          }
  
          // existing rows, value checks
!         Constraint.checkReferencedRows(table, fkcol, exportindex);
  
          // create
          HsqlName iname   = table.database.nameManager.newAutoName("IDX");
--- 140,146 ----
          }
  
          // existing rows, value checks
!         Constraint.checkReferencedRows(session, table, fkcol, exportindex);
  
          // create
          HsqlName iname   = table.database.nameManager.newAutoName("IDX");
***************
*** 195,208 ****
              newindex = table.createIndex(col, name, unique, constraint,
                                           forward);
          } else {
!             Table tn = table.moveDefinition(null, null,
!                                             table.getColumnCount(), 0);
  
              newindex = tn.createIndexStructure(col, name, unique, constraint,
                                                 forward);
  
!             tn.moveData(session, table, table.getColumnCount(), 0);
!             tn.updateConstraintsTables(table, table.getColumnCount(), 0);
  
              int index = table.database.getTableIndex(table);
  
--- 196,208 ----
              newindex = table.createIndex(col, name, unique, constraint,
                                           forward);
          } else {
!             Table tn = table.moveDefinition(null, null, -1, 0);
  
              newindex = tn.createIndexStructure(col, name, unique, constraint,
                                                 forward);
  
!             tn.moveData(session, table, -1, 0);
!             tn.updateConstraintsTables(table, -1, 0);
  
              int index = table.database.getTableIndex(table);
  
***************
*** 221,226 ****
--- 221,230 ----
  
      void addPrimaryKey(int[] cols, HsqlName name) throws HsqlException {
  
+         if (name == null) {
+             name = table.makeSysPKName();
+         }
+ 
          if (table.database.constraintNameList.containsName(name.name)) {
              throw Trace.error(Trace.CONSTRAINT_ALREADY_EXISTS, name.name);
          }
***************
*** 239,246 ****
  
          Table tn = table.moveDefinitionPK(name, cols);
  
!         tn.moveData(session, table, table.getColumnCount(), 0);
!         tn.updateConstraintsTables(table, table.getColumnCount(), 0);
  
          int index = table.database.getTableIndex(table);
  
--- 243,250 ----
  
          Table tn = table.moveDefinitionPK(name, cols);
  
!         tn.moveData(session, table, -1, 0);
!         tn.updateConstraintsTables(table, -1, 0);
  
          int index = table.database.getTableIndex(table);
  
***************
*** 348,358 ****
          if (table.isIndexingMutable()) {
              table.dropIndex(indexname);
          } else {
!             Table tn = table.moveDefinition(indexname, null,
!                                             table.getColumnCount(), 0);
  
!             tn.moveData(session, table, table.getColumnCount(), 0);
!             tn.updateConstraintsTables(table, table.getColumnCount(), 0);
  
              int i = table.database.getTableIndex(table);
  
--- 352,361 ----
          if (table.isIndexingMutable()) {
              table.dropIndex(indexname);
          } else {
!             Table tn = table.moveDefinition(indexname, null, -1, 0);
  
!             tn.moveData(session, table, -1, 0);
!             tn.updateConstraintsTables(table, -1, 0);
  
              int i = table.database.getTableIndex(table);
  
***************
*** 367,385 ****
  
      /**
       *
!      * @param  column
       * @param  colindex
!      * @param  adjust +1 or -1
       * @throws  HsqlException
       */
!     void addOrDropColumn(Column column, int colindex,
!                          int adjust) throws HsqlException {
  
          if (table.isText()) {
              throw Trace.error(Trace.OPERATION_NOT_SUPPORTED);
          }
  
!         if (adjust == -1) {
              table.database.checkColumnIsInView(
                  table.getName().name,
                  table.getColumn(colindex).columnName.name);
--- 370,388 ----
  
      /**
       *
!      * @param  column is null if adjust is -1
       * @param  colindex
!      * @param  adjust +1, 0 -1
       * @throws  HsqlException
       */
!     void addDropRetypeColumn(Column column, int colindex,
!                              int adjust) throws HsqlException {
  
          if (table.isText()) {
              throw Trace.error(Trace.OPERATION_NOT_SUPPORTED);
          }
  
!         if (adjust == -1 || adjust == 0) {
              table.database.checkColumnIsInView(
                  table.getName().name,
                  table.getColumn(colindex).columnName.name);
***************
*** 467,470 ****
--- 470,593 ----
  
          table.database.constraintNameList.removeName(name);
      }
+ 
+     void reTypeColumn(Column oldCol, Column newCol) throws HsqlException {
+ 
+         boolean notallowed = false;
+         int     oldtype    = oldCol.getType();
+         int     newtype    = newCol.getType();
+ 
+         switch (newtype) {
+ 
+             case Types.BINARY :
+             case Types.VARBINARY :
+             case Types.LONGVARBINARY :
+             case Types.OTHER :
+             case Types.JAVA_OBJECT :
+                 notallowed = !table.isEmpty();
+         }
+ 
+         switch (oldtype) {
+ 
+             case Types.BINARY :
+             case Types.VARBINARY :
+             case Types.LONGVARBINARY :
+             case Types.OTHER :
+             case Types.JAVA_OBJECT :
+                 notallowed = !table.isEmpty();
+                 break;
+ 
+             case Types.TINYINT :
+             case Types.SMALLINT :
+             case Types.INTEGER :
+             case Types.BIGINT :
+             case Types.REAL :
+             case Types.FLOAT :
+             case Types.DOUBLE :
+             case Types.NUMERIC :
+             case Types.DECIMAL :
+                 switch (newtype) {
+ 
+                     case Types.DATE :
+                     case Types.TIME :
+                     case Types.TIMESTAMP :
+                         notallowed = !table.isEmpty();
+                     default :
+                 }
+                 break;
+ 
+             case Types.DATE :
+             case Types.TIME :
+             case Types.TIMESTAMP :
+                 switch (newtype) {
+ 
+                     case Types.TINYINT :
+                     case Types.SMALLINT :
+                     case Types.INTEGER :
+                     case Types.BIGINT :
+                     case Types.REAL :
+                     case Types.FLOAT :
+                     case Types.DOUBLE :
+                     case Types.NUMERIC :
+                     case Types.DECIMAL :
+                         notallowed = !table.isEmpty();
+                     default :
+                 }
+                 break;
+         }
+ 
+         if (notallowed) {
+             throw Trace.error(Trace.INVALID_CONVERSION);
+         }
+ 
+         int colindex = table.getColumnNr(oldCol.columnName.name);
+ 
+         if (table.getPrimaryKey().length > 1) {
+ 
+             // if there is a multi-column PK, do not change the PK attributes
+             if (newCol.isIdentity()) {
+                 throw Trace.error(Trace.SECOND_PRIMARY_KEY);
+             }
+ 
+             newCol.setPrimaryKey(oldCol.isPrimaryKey());
+ 
+             if (ArrayUtil.find(table.getPrimaryKey(), colindex) != -1) {
+                 newCol.setNullable(false);
+             }
+         } else if (table.hasPrimaryKey()) {
+             if (oldCol.isPrimaryKey()) {
+                 newCol.setPrimaryKey(true);
+                 newCol.setNullable(false);
+             } else if (newCol.isPrimaryKey()) {
+                 throw Trace.error(Trace.SECOND_PRIMARY_KEY);
+             }
+         } else if (newCol.isPrimaryKey()) {
+ 
+             // use a better error message
+             throw Trace.error(Trace.SECOND_PRIMARY_KEY);
+         }
+ 
+         table.database.checkColumnIsInView(
+             table.getName().name, table.getColumn(colindex).columnName.name);
+         table.checkColumnInCheckConstraint(
+             table.getColumn(colindex).columnName.name);
+         table.checkColumnInFKConstraint(oldCol.columnName.name);
+         checkConvertColDataType(oldCol, newCol);
+         addDropRetypeColumn(newCol, colindex, 0);
+     }
+ 
+     void checkConvertColDataType(Column oldCol,
+                                  Column newCol) throws HsqlException {
+ 
+         int         colindex = table.getColumnNr(oldCol.columnName.name);
+         RowIterator it       = table.rowIterator(null);
+ 
+         while (it.hasNext()) {
+             Row    row = it.next();
+             Object o   = row.getData()[colindex];
+ 
+             Column.convertObject(session, o, newCol.getType(),
+                                  newCol.getSize(), newCol.getScale());
+         }
+     }
  }
*** misc/hsqldb/src/org/hsqldb/TextTable.java	Wed Mar  2 14:50:57 2005
--- misc/build/hsqldb/src/org/hsqldb/TextTable.java	Thu Mar 31 10:35:27 2005
***************
*** 197,203 ****
  
      public String getHeader() {
  
!         String header = ((TextCache) cache).getHeader();
  
          return header == null ? null
                                : StringConverter.toQuotedString(header, '\"',
--- 197,204 ----
  
      public String getHeader() {
  
!         String header = cache == null ? null
!                                       : ((TextCache) cache).getHeader();
  
          return header == null ? null
                                : StringConverter.toQuotedString(header, '\"',
*** misc/hsqldb/src/org/hsqldb/Token.java	Wed Mar  2 14:50:57 2005
--- misc/build/hsqldb/src/org/hsqldb/Token.java	Thu Mar 31 10:35:27 2005
***************
*** 338,348 ****
--- 338,350 ----
      static final String        T_CHECKPOINT     = "CHECKPOINT";
      static final String        T_CLASS          = "CLASS";
      static final String        T_COALESCE       = "COALESCE";
+     static final String        T_COLLATION      = "COLLATION";
      static final String        T_COMPACT        = "COMPACT";
      public static final String T_COMPRESSED     = "COMPRESSED";
      static final String        T_CONCAT         = "CONCAT";
      static final String        T_CONVERT        = "CONVERT";
      static final String        T_COUNT          = "COUNT";
+     static final String        T_DATABASE       = "DATABASE";
      static final String        T_DEFRAG         = "DEFRAG";
      static final String        T_DESC           = "DESC";
      static final String        T_EVERY          = "EVERY";
***************
*** 366,371 ****
--- 368,375 ----
      static final String        T_NOW            = "NOW";
      static final String        T_NOWAIT         = "NOWAIT";
      static final String        T_NULLIF         = "NULLIF";
+     static final String        T_NVL            = "NVL";
+     static final String        T_OFFSET         = "OFFSET";
      static final String        T_PASSWORD       = "PASSWORD";
      static final String        T_PLAN           = "PLAN";
      static final String        T_POSITION       = "POSITION";
***************
*** 687,692 ****
--- 691,698 ----
      static final int STDDEV_SAMP = 333;
      static final int DEFRAG      = 334;
      static final int INCREMENT   = 335;
+     static final int TOCHAR      = 336;
+     static final int DATABASE    = 337;
  
      //
      static {
***************
*** 718,723 ****
--- 724,730 ----
          commandSet.put(T_CONNECT, CONNECT);
          commandSet.put(T_CONSTRAINT, CONSTRAINT);
          commandSet.put(T_CREATE, CREATE);
+         commandSet.put(T_DATABASE, DATABASE);
          commandSet.put(T_DELETE, DELETE);
          commandSet.put(T_DEFRAG, DEFRAG);
          commandSet.put(T_DISCONNECT, DISCONNECT);
***************
*** 797,819 ****
  
          /* "LEFT" ,*/
          String[] keyword = {
!             Token.T_AS, Token.T_AND, Token.T_ALL, Token.T_AVG, Token.T_BY,
!             Token.T_BETWEEN, Token.T_BOTH, Token.T_CALL, Token.T_CASE,
!             Token.T_CASEWHEN, Token.T_CAST, Token.T_CONVERT, Token.T_CONCAT,
!             Token.T_COUNT, Token.T_COALESCE, Token.T_DISTINCT, Token.T_ELSE,
!             Token.T_END, Token.T_EVERY, Token.T_EXISTS, Token.T_EXCEPT,
!             Token.T_EXTRACT, Token.T_FOR, Token.T_FROM, Token.T_GROUP,
!             Token.T_HAVING, Token.T_IF, Token.T_INTO, Token.T_IFNULL,
!             Token.T_IS, Token.T_IN, Token.T_INTERSECT, Token.T_JOIN,
!             Token.T_INNER, Token.T_LEADING, Token.T_LIKE, Token.T_MAX,
!             Token.T_MIN, Token.T_NEXT, Token.T_NULLIF, Token.T_NOT,
!             Token.T_MINUS, Token.T_ON, Token.T_ORDER, Token.T_OR,
!             Token.T_OUTER, Token.T_POSITION, Token.T_PRIMARY, Token.T_SELECT,
!             Token.T_SET, Token.T_SOME, Token.T_STDDEV_POP,
!             Token.T_STDDEV_SAMP, Token.T_SUBSTRING, Token.T_SUM, Token.T_THEN,
!             Token.T_TO, Token.T_TRAILING, Token.T_TRIM, Token.T_UNIQUE,
!             Token.T_UNION, Token.T_VALUES, Token.T_VAR_POP, Token.T_VAR_SAMP,
!             Token.T_WHEN, Token.T_WHERE,
          };
  
          for (int i = 0; i < keyword.length; i++) {
--- 804,826 ----
  
          /* "LEFT" ,*/
          String[] keyword = {
!             Token.T_AS, Token.T_AND, Token.T_ALL, Token.T_ANY, Token.T_AVG,
!             Token.T_BY, Token.T_BETWEEN, Token.T_BOTH, Token.T_CALL,
!             Token.T_CASE, Token.T_CASEWHEN, Token.T_CAST, Token.T_CONVERT,
!             Token.T_CONCAT, Token.T_COUNT, Token.T_COALESCE, Token.T_DISTINCT,
!             Token.T_ELSE, Token.T_END, Token.T_EVERY, Token.T_EXISTS,
!             Token.T_EXCEPT, Token.T_EXTRACT, Token.T_FOR, Token.T_FROM,
!             Token.T_GROUP, Token.T_HAVING, Token.T_IF, Token.T_INTO,
!             Token.T_IFNULL, Token.T_IS, Token.T_IN, Token.T_INTERSECT,
!             Token.T_JOIN, Token.T_INNER, Token.T_LEADING, Token.T_LIKE,
!             Token.T_MAX, Token.T_MIN, Token.T_NEXT, Token.T_NULLIF,
!             Token.T_NOT, Token.T_NVL, Token.T_MINUS, Token.T_ON,
!             Token.T_ORDER, Token.T_OR, Token.T_OUTER, Token.T_POSITION,
!             Token.T_PRIMARY, Token.T_SELECT, Token.T_SET, Token.T_SOME,
!             Token.T_STDDEV_POP, Token.T_STDDEV_SAMP, Token.T_SUBSTRING,
!             Token.T_SUM, Token.T_THEN, Token.T_TO, Token.T_TRAILING,
!             Token.T_TRIM, Token.T_UNIQUE, Token.T_UNION, Token.T_VALUES,
!             Token.T_VAR_POP, Token.T_VAR_SAMP, Token.T_WHEN, Token.T_WHERE,
          };
  
          for (int i = 0; i < keyword.length; i++) {
*** misc/hsqldb/src/org/hsqldb/Tokenizer.java	Wed Mar  2 14:50:57 2005
--- misc/build/hsqldb/src/org/hsqldb/Tokenizer.java	Thu Mar 31 10:35:27 2005
***************
*** 173,179 ****
       */
      void back() throws HsqlException {
  
!         Trace.doAssert(!bWait, "back");
  
          nextTokenIndex = iIndex;
          iIndex         = tokenIndex;
--- 173,181 ----
       */
      void back() throws HsqlException {
  
!         if (bWait) {
!             Trace.doAssert(!bWait, "back");
!         }
  
          nextTokenIndex = iIndex;
          iIndex         = tokenIndex;
***************
*** 181,188 ****
      }
  
      /**
!      * Method declaration
!      *
       *
       * @param match
       *
--- 183,189 ----
      }
  
      /**
!      * get the given token or throw
       *
       * @param match
       *
***************
*** 200,211 ****
          }
      }
  
!     static void matchThis(String match, String token) throws HsqlException {
  
!         if (!token.equals(match)) {
              throw Trace.error(Trace.UNEXPECTED_TOKEN, Trace.TOKEN_REQUIRED,
                                new Object[] {
!                 token, match
              });
          }
      }
--- 201,212 ----
          }
      }
  
!     void matchThis(String match) throws HsqlException {
  
!         if (!sToken.equals(match)) {
              throw Trace.error(Trace.UNEXPECTED_TOKEN, Trace.TOKEN_REQUIRED,
                                new Object[] {
!                 sToken, match
              });
          }
      }
*** misc/hsqldb/src/org/hsqldb/Trace.java	Wed Mar  2 14:50:57 2005
--- misc/build/hsqldb/src/org/hsqldb/Trace.java	Thu Mar 31 10:35:27 2005
***************
*** 117,123 ****
                              NEED_AGGREGATE                            = 14,
                              SUM_OF_NON_NUMERIC                        = 15,
                              WRONG_DATA_TYPE                           = 16,
!                             SINGLE_VALUE_EXPECTED                     = 17,
                              SERIALIZATION_FAILURE                     = 18,
                              TRANSFER_CORRUPTED                        = 19,
                              FUNCTION_NOT_SUPPORTED                    = 20,
--- 117,123 ----
                              NEED_AGGREGATE                            = 14,
                              SUM_OF_NON_NUMERIC                        = 15,
                              WRONG_DATA_TYPE                           = 16,
!                             CARDINALITY_VIOLATION_NO_SUBCLASS         = 17,
                              SERIALIZATION_FAILURE                     = 18,
                              TRANSFER_CORRUPTED                        = 19,
                              FUNCTION_NOT_SUPPORTED                    = 20,
***************
*** 217,228 ****
                              DatabaseScriptReader_readExistingData     = 114,
                              Message_Pair                              = 115,
                              HsqlDatabaseProperties                    = 116,
!                             not_used                                  = 117,
                              JDBC_INVALID_BRI_SCOPE                    = 118,
                              JDBC_NO_RESULT_SET_METADATA               = 119,
                              JDBC_NO_RESULT_SET                        = 120,
                              MISSING_CLOSEBRACKET                      = 121,
!                             TableFilter_findFirst                     = 122,
                              Table_moveDefinition                      = 123,
                              STRING_DATA_TRUNCATION                    = 124,
                              QUOTED_IDENTIFIER_REQUIRED                = 125,
--- 217,228 ----
                              DatabaseScriptReader_readExistingData     = 114,
                              Message_Pair                              = 115,
                              HsqlDatabaseProperties                    = 116,
!                             INVALID_TRANSACTION_STATE_NO_SUBCLASS     = 117,
                              JDBC_INVALID_BRI_SCOPE                    = 118,
                              JDBC_NO_RESULT_SET_METADATA               = 119,
                              JDBC_NO_RESULT_SET                        = 120,
                              MISSING_CLOSEBRACKET                      = 121,
!                             ITSNS_OVERWRITE                           = 122,
                              Table_moveDefinition                      = 123,
                              STRING_DATA_TRUNCATION                    = 124,
                              QUOTED_IDENTIFIER_REQUIRED                = 125,
***************
*** 253,259 ****
                              TEXT_TABLE_HEADER                         = 150,
                              TextDatabaseRowOutput_checkConvertString2 = 151,
                              TextDatabaseRowOutput_writeIntData        = 152,
!                             ORDER_BY_POSITION                         = 153,
                              JDBC_STATEMENT_NOT_ROW_COUNT              = 154,
                              JDBC_STATEMENT_NOT_RESULTSET              = 155,
                              AMBIGUOUS_COLUMN_REFERENCE                = 156,
--- 253,259 ----
                              TEXT_TABLE_HEADER                         = 150,
                              TextDatabaseRowOutput_checkConvertString2 = 151,
                              TextDatabaseRowOutput_writeIntData        = 152,
!                             INVALID_LIMIT                             = 153,
                              JDBC_STATEMENT_NOT_ROW_COUNT              = 154,
                              JDBC_STATEMENT_NOT_RESULTSET              = 155,
                              AMBIGUOUS_COLUMN_REFERENCE                = 156,
***************
*** 263,275 ****
                              TOKEN_REQUIRED                            = 160,
                              Logger_checkFilesInJar                    = 161,
                              Logger_checkFilesInJar1                   = 162,
!                             Logger_checkFilesInJar2                   = 163,
                              TRIGGER_ALREADY_EXISTS                    = 164,
                              ASSERT_DIRECT_EXEC_WITH_PARAM             = 165,
                              DataFileCache_backup                      = 166,
                              Expression_compareValues                  = 167,
!                             Parser_parseLimit1                        = 168,
!                             Parser_parseLimit2                        = 169,
                              SQL_CONSTRAINT_REQUIRED                   = 170,
                              TableWorks_dropConstraint                 = 171,
                              TEXT_TABLE_SOURCE_FILENAME                = 172,
--- 263,275 ----
                              TOKEN_REQUIRED                            = 160,
                              Logger_checkFilesInJar                    = 161,
                              Logger_checkFilesInJar1                   = 162,
!                             ORDER_LIMIT_REQUIRED                      = 163,
                              TRIGGER_ALREADY_EXISTS                    = 164,
                              ASSERT_DIRECT_EXEC_WITH_PARAM             = 165,
                              DataFileCache_backup                      = 166,
                              Expression_compareValues                  = 167,
!                             INVALID_LIMIT_EXPRESSION                  = 168,
!                             INVALID_TOP_EXPRESSION                    = 169,
                              SQL_CONSTRAINT_REQUIRED                   = 170,
                              TableWorks_dropConstraint                 = 171,
                              TEXT_TABLE_SOURCE_FILENAME                = 172,
***************
*** 308,314 ****
                              CREATE_TRIGGER_COMMAND_2                  = 205,
                              BAD_SAVEPOINT_NAME                        = 206,
                              DataFileCache_defrag                      = 207,
!                             DataFileCache_closeFile                   = 208,
                              DataFileCache_makeRow                     = 209,
                              DataFileCache_open                        = 210,
                              DataFileCache_close                       = 211,
--- 308,314 ----
                              CREATE_TRIGGER_COMMAND_2                  = 205,
                              BAD_SAVEPOINT_NAME                        = 206,
                              DataFileCache_defrag                      = 207,
!                             INVALID_COLLATION_NAME_NO_SUBCLASS        = 208,
                              DataFileCache_makeRow                     = 209,
                              DataFileCache_open                        = 210,
                              DataFileCache_close                       = 211,
***************
*** 350,356 ****
          "37000 Need aggregate function or group by",                    //
          "37000 Sum on non-numeric data not allowed",                    //
          "37000 Wrong data type",                                        //
!         "37000 Single value expected",                                  //
          "40001 Serialization failure",                                  //
          "40001 Transfer corrupted",                                     //
          "IM001 This function is not supported",                         //
--- 350,356 ----
          "37000 Need aggregate function or group by",                    //
          "37000 Sum on non-numeric data not allowed",                    //
          "37000 Wrong data type",                                        //
!         "21000 Single value expected",                                  //
          "40001 Serialization failure",                                  //
          "40001 Transfer corrupted",                                     //
          "IM001 This function is not supported",                         //
***************
*** 450,461 ****
          " line: $$ $$",                                                 // DatabaseScriptReader_readExistingData
          " $$ $$",                                                       // Function_Function
          " $$.properties $$",                                            // HsqlDatabaseProperties_load
!         "",                                                             // unused
          "invalid scope value",                                          // jdbcDatabaseMetaData_getBestRowIdentifier
          "result set is null",                                           // jdbcResultSetMetaData_jdbcResultSetMetaData
          "result set is closed",                                         // jdbcResultSetMetaData_jdbcResultSetMetaData_2
          "37000 missing )",                                              // MISSING_CLOSEBRACKET
!         "37000 an index is required on table $$, column $$",            // TableFilter_findFirst
          "37000 there is an index on the column to be removed",          // Table_moveDefinition
          "22001 string too long",                                        //
          "00000 quoted identifier required",                             // SET PROPERTY "name" "value"
--- 450,461 ----
          " line: $$ $$",                                                 // DatabaseScriptReader_readExistingData
          " $$ $$",                                                       // Function_Function
          " $$.properties $$",                                            // HsqlDatabaseProperties_load
!         "25000 invalid transaction state",                              // INVALID_TRANSACTION_STATE_NO_SUBCLASS
          "invalid scope value",                                          // jdbcDatabaseMetaData_getBestRowIdentifier
          "result set is null",                                           // jdbcResultSetMetaData_jdbcResultSetMetaData
          "result set is closed",                                         // jdbcResultSetMetaData_jdbcResultSetMetaData_2
          "37000 missing )",                                              // MISSING_CLOSEBRACKET
!         "row has been modified by another transaction",                 // TableFilter_findFirst
          "37000 there is an index on the column to be removed",          // Table_moveDefinition
          "22001 string too long",                                        //
          "00000 quoted identifier required",                             // SET PROPERTY "name" "value"
***************
*** 486,492 ****
          "22001 header not allowed or too long",                         // TEXT_TABLE_HEADER
          "22001 separator not allowed in unquoted string",               // 151 TextDatabaseRowOutput_checkConvertString2
          "not implemented",                                              // TextDatabaseRowOutput_writeIntData
!         "00000 ORDER BY must be at the end of the statement",           //
          "00000 Statement does not generate a row count",                //
          "00000 Statement does not generate a result set",               //
          "S0022 ambiguous Column reference",                             //
--- 486,492 ----
          "22001 header not allowed or too long",                         // TEXT_TABLE_HEADER
          "22001 separator not allowed in unquoted string",               // 151 TextDatabaseRowOutput_checkConvertString2
          "not implemented",                                              // TextDatabaseRowOutput_writeIntData
!         "00000 LIMIT or TOP not allowed",                               //
          "00000 Statement does not generate a row count",                //
          "00000 Statement does not generate a result set",               //
          "S0022 ambiguous Column reference",                             //
***************
*** 496,508 ****
          " $$, requires $$",                                             // Tokenizer.getThis()
          "path is null",                                                 // 161
          "file does not exist: ",                                        //
!         "wrong resource protocol: ",                                    //
          "S0002 Trigger already exists",                                 //
          "S0000 direct execute with param count > 0",                    //
          "while creating ",                                              // DataFileCache_backup
          "Expression.compareValues",                                     // Expression_compareValues
!         "LIMIT n m",                                                    // Parser_parseLimit1
!         "TOP n",                                                        // Parser_parseLimit2
          "S0011 primary or unique constraint required on main table",    //
          " $$ in table: $$",                                             // 171
          "no file name specified for source",                            //
--- 496,508 ----
          " $$, requires $$",                                             // Tokenizer.getThis()
          "path is null",                                                 // 161
          "file does not exist: ",                                        //
!         "00000 ORDER BY with LIMIT required",                           //
          "S0002 Trigger already exists",                                 //
          "S0000 direct execute with param count > 0",                    //
          "while creating ",                                              // DataFileCache_backup
          "Expression.compareValues",                                     // Expression_compareValues
!         "LIMIT clause",                                                 //
!         "TOP clause",                                                   //
          "S0011 primary or unique constraint required on main table",    //
          " $$ in table: $$",                                             // 171
          "no file name specified for source",                            //
***************
*** 541,547 ****
          "loading trigger class ",                                       // DatabaseCommandInterpreter_processCreateTrigger2
          "missing or zero-length savepoint name",                        // DatabaseCommandInterpreter_processSavepoint
          "error $$ during defrag - file $$",                             // DataFileCache_defrag
!         "error $$ during shutdown - file $$",                           // DataFileCache_closeFile
          "error $$ reading row - file $$",                               // DataFileCache_makeRow
          "error $$ opening file - file $$",                              // DataFileCache_makeRow
          "error $$ closing file - file $$",                              // 211 DataFileCache_makeRow
--- 541,547 ----
          "loading trigger class ",                                       // DatabaseCommandInterpreter_processCreateTrigger2
          "missing or zero-length savepoint name",                        // DatabaseCommandInterpreter_processSavepoint
          "error $$ during defrag - file $$",                             // DataFileCache_defrag
!         "invalid collation name",                                       // INVALID_COLLATION_NAME_NO_SUBCLASS
          "error $$ reading row - file $$",                               // DataFileCache_makeRow
          "error $$ opening file - file $$",                              // DataFileCache_makeRow
          "error $$ closing file - file $$",                              // 211 DataFileCache_makeRow
*** misc/hsqldb/src/org/hsqldb/Transaction.java	Wed Mar  2 14:50:57 2005
--- misc/build/hsqldb/src/org/hsqldb/Transaction.java	Thu Mar 31 10:35:27 2005
***************
*** 73,82 ****
   */
  class Transaction {
  
!     private boolean isDelete;
!     private Table   tTable;
!     private Row     row;
!     long            SCN;
  
      /**
       * Constructor. <p>
--- 73,82 ----
   */
  class Transaction {
  
!     boolean isDelete;
!     Table   tTable;
!     Row     row;
!     long    SCN;
  
      /**
       * Constructor. <p>
*** misc/hsqldb/src/org/hsqldb/TxManager.java	Thu Mar 31 10:34:36 2005
--- misc/build/hsqldb/src/org/hsqldb/TxManager.java	Thu Mar 31 10:35:27 2005
***************
*** 1 ****
! dummy
--- 1,216 ----
! /* Copyright (c) 2001-2005, The HSQL Development Group
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms, with or without
!  * modification, are permitted provided that the following conditions are met:
!  *
!  * Redistributions of source code must retain the above copyright notice, this
!  * list of conditions and the following disclaimer.
!  *
!  * Redistributions in binary form must reproduce the above copyright notice,
!  * this list of conditions and the following disclaimer in the documentation
!  * and/or other materials provided with the distribution.
!  *
!  * Neither the name of the HSQL Development Group nor the names of its
!  * contributors may be used to endorse or promote products derived from this
!  * software without specific prior written permission.
!  *
!  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
!  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
!  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
!  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
!  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
!  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
!  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
!  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
!  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
!  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
!  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!  */
! 
! 
! package org.hsqldb;
! 
! import org.hsqldb.lib.*;
! 
! class TxManager {
! 
!     LongKeyIntValueHashMap rowSessionMap;
! 
!     TxManager() {
!         rowSessionMap = new LongKeyIntValueHashMap();
!     }
! 
!     void checkDelete(Session session, Row row) throws HsqlException {}
! 
!     void checkDelete(Session session,
!                      HashMappedList rowSet) throws HsqlException {
! 
!         int sessionid = session.getId();
! 
!         for (int i = 0, size = rowSet.size(); i < size; i++) {
!             Row  row   = (Row) rowSet.getKey(i);
!             long rowid = row.getId();
! 
!             if (rowSessionMap.get(rowid, sessionid) != sessionid) {
!                 throw Trace.error(Trace.INVALID_TRANSACTION_STATE_NO_SUBCLASS,
!                                   Trace.ITSNS_OVERWRITE);
!             }
!         }
!     }
! 
!     void checkDelete(Session session,
!                      HsqlArrayList rowSet) throws HsqlException {
! 
!         int sessionid = session.getId();
! 
!         for (int i = 0, size = rowSet.size(); i < size; i++) {
!             Row  row   = (Row) rowSet.get(i);
!             long rowid = row.getId();
! 
!             if (rowSessionMap.get(rowid, sessionid) != sessionid) {
!                 throw Trace.error(Trace.INVALID_TRANSACTION_STATE_NO_SUBCLASS,
!                                   Trace.ITSNS_OVERWRITE);
!             }
!         }
!     }
! 
!     void commit(Session session) {
! 
!         Object[] list = session.transactionList.getArray();
!         int      size = session.transactionList.size();
! 
!         for (int i = 0; i < size; i++) {
!             Transaction tx    = (Transaction) list[i];
!             long        rowid = tx.row.getId();
! 
!             rowSessionMap.remove(rowid);
!         }
! 
!         session.transactionList.clear();
!         session.savepoints.clear();
!     }
! 
!     synchronized void rollback(Session session) {
! 
!         int size = session.transactionList.size();
! 
!         rollbackTransactions(session, 0, false);
!         session.savepoints.clear();
!     }
! 
!     void rollbackSavepoint(Session session,
!                            String name) throws HsqlException {
! 
!         int index = session.savepoints.getIndex(name);
! 
!         if (index < 1) {
!             throw Trace.error(Trace.SAVEPOINT_NOT_FOUND, name);
!         }
! 
!         Integer oi    = (Integer) session.savepoints.get(index);
!         int     limit = oi.intValue();
! 
!         rollbackTransactions(session, limit, false);
! 
!         while (session.savepoints.size() > index) {
!             session.savepoints.remove(session.savepoints.size() - 1);
!         }
!     }
! 
!     void rollbackTransactions(Session session, int limit, boolean log) {
! 
!         Object[] list = session.transactionList.getArray();
!         int      size = session.transactionList.size();
! 
!         for (int i = size - 1; i >= limit; i--) {
!             Transaction tx = (Transaction) list[i];
! 
!             tx.rollback(session, false);
!         }
! 
!         for (int i = limit; i < size; i++) {
!             Transaction tx    = (Transaction) list[i];
!             long        rowid = tx.row.getId();
! 
!             rowSessionMap.remove(rowid);
!         }
! 
!         session.transactionList.setSize(limit);
!     }
! 
!     void addTransaction(Session session, Transaction transaction) {
!         rowSessionMap.put(transaction.row.getId(), session.getId());
!     }
! 
!     /**
!      * Return an array of all transactions sorted by System Change No.
!      */
!     Transaction[] getTransactionList(Session[] sessions) {
! 
!         int[]         tIndex = new int[sessions.length];
!         Transaction[] transactions;
!         int           transactionCount = 0;
! 
!         {
!             int actioncount = 0;
! 
!             for (int i = 0; i < sessions.length; i++) {
!                 actioncount += sessions[i].getTransactionSize();
!             }
! 
!             transactions = new Transaction[actioncount];
!         }
! 
!         while (true) {
!             boolean found        = false;
!             long    minChangeNo  = Long.MAX_VALUE;
!             int     sessionIndex = 0;
! 
!             // find the lowest available SCN across all sessions
!             for (int i = 0; i < sessions.length; i++) {
!                 int tSize = sessions[i].getTransactionSize();
! 
!                 if (tIndex[i] < tSize) {
!                     Transaction current =
!                         (Transaction) sessions[i].transactionList.get(
!                             tIndex[i]);
! 
!                     if (current.SCN < minChangeNo) {
!                         minChangeNo  = current.SCN;
!                         sessionIndex = i;
!                     }
! 
!                     found = true;
!                 }
!             }
! 
!             if (!found) {
!                 break;
!             }
! 
!             HsqlArrayList currentList =
!                 sessions[sessionIndex].transactionList;
! 
!             for (; tIndex[sessionIndex] < currentList.size(); ) {
!                 Transaction current =
!                     (Transaction) currentList.get(tIndex[sessionIndex]);
! 
!                 // if the next change no is in this session, continue adding
!                 if (current.SCN == minChangeNo + 1) {
!                     minChangeNo++;
!                 }
! 
!                 if (current.SCN == minChangeNo) {
!                     transactions[transactionCount++] = current;
! 
!                     tIndex[sessionIndex]++;
!                 } else {
!                     break;
!                 }
!             }
!         }
! 
!         return null;
!     }
! }
*** misc/hsqldb/src/org/hsqldb/View.java	Wed Mar  2 14:51:00 2005
--- misc/build/hsqldb/src/org/hsqldb/View.java	Thu Mar 31 10:35:27 2005
***************
*** 119,125 ****
                                this.database, tokenizer);
  
          viewSubQuery = p.parseSubquery(brackets, colList, true,
!                                        Expression.QUERY);
  
          p.setAsView(this);
  
--- 119,125 ----
                                this.database, tokenizer);
  
          viewSubQuery = p.parseSubquery(brackets, colList, true,
!                                        Expression.VIEW);
  
          p.setAsView(this);
  
***************
*** 127,133 ****
          workingTable   = viewSubQuery.table;
          viewSelect     = viewSubQuery.select;
  
!         viewSelect.prepareResult();
  
          Result.ResultMetaData metadata = viewSelect.resultMetaData;
          int                   columns  = viewSelect.iResultLen;
--- 127,133 ----
          workingTable   = viewSubQuery.table;
          viewSelect     = viewSubQuery.select;
  
!         viewSelect.prepareResult(database);
  
          Result.ResultMetaData metadata = viewSelect.resultMetaData;
          int                   columns  = viewSelect.iResultLen;
*** misc/hsqldb/src/org/hsqldb/jdbc/jdbcClob.java	Wed Mar  2 14:50:49 2005
--- misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcClob.java	Thu Mar 31 10:35:29 2005
***************
*** 275,280 ****
--- 275,282 ----
          final long   dlen  = ldata.length();
          final long   sslen = searchstr.length();
  
+         start--;    //***** FOIRGOT THIS *******
+ 
  // This is potentially much less expensive than materializing a large
  // substring from some other vendor's CLOB.  Indeed, we should probably
  // do the comparison piecewise, using an in-memory buffer (or temp-files
*** misc/hsqldb/src/org/hsqldb/jdbc/jdbcConnection.java	Wed Mar  2 14:50:49 2005
--- misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcConnection.java	Thu Mar 31 10:35:29 2005
***************
*** 1260,1270 ****
       * <!-- end generic documentation -->
       * <!-- start release-specific documentation -->
       * <div class="ReleaseSpecificDocumentation">
-      * <h3>HSQLDB-Specific Information:</h3> <p>
-      *
-      * Up to and including 1.7.1, HSQLDB supports only
-      * <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>. <p>
-      *
       * </div> <!-- end release-specific documentation -->
       *
       * @param level one of the following <code>Connection</code>
--- 1260,1265 ----
***************
*** 1286,1294 ****
  
          checkClosed();
  
!         if (level != Connection.TRANSACTION_READ_UNCOMMITTED) {
              throw Util.notSupported;
          }
      }
  
      /**
--- 1281,1300 ----
  
          checkClosed();
  
!         boolean ok = level == Connection.TRANSACTION_READ_UNCOMMITTED
!                      || level == Connection.TRANSACTION_READ_COMMITTED
!                      || level == Connection.TRANSACTION_REPEATABLE_READ
!                      || level == Connection.TRANSACTION_SERIALIZABLE;
! 
!         if (!ok) {
              throw Util.notSupported;
          }
+ 
+         try {
+             sessionProxy.setIsolation(level);
+         } catch (HsqlException e) {
+             throw Util.sqlException(e);
+         }
      }
  
      /**
***************
*** 1324,1330 ****
  
          checkClosed();
  
!         return Connection.TRANSACTION_READ_UNCOMMITTED;
      }
  
      /**
--- 1330,1340 ----
  
          checkClosed();
  
!         try {
!             return sessionProxy.getIsolation();
!         } catch (HsqlException e) {
!             throw Util.sqlException(e);
!         }
      }
  
      /**
*** misc/hsqldb/src/org/hsqldb/jdbc/jdbcDatabaseMetaData.java	Wed Mar  2 14:50:50 2005
--- misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcDatabaseMetaData.java	Thu Mar 31 10:35:29 2005
***************
*** 2902,2908 ****
       * <!-- start release-specific documentation -->
       * <div class="ReleaseSpecificDocumentation">
       * <h3>HSQLDB-Specific Information</h3>
!      * HSQLDB supports only <code>TRANSACTION_READ_UNCOMMITED</code>.
       * </div>
       * <!-- end release-specific documentation -->
       *
--- 2902,2909 ----
       * <!-- start release-specific documentation -->
       * <div class="ReleaseSpecificDocumentation">
       * <h3>HSQLDB-Specific Information</h3>
!      * HSQLDB supports <code>TRANSACTION_READ_UNCOMMITED</code> and
!      * <code>TRANSACTION_READ_COMMITED</code>.
       * </div>
       * <!-- end release-specific documentation -->
       *
***************
*** 2915,2921 ****
       */
      public boolean supportsTransactionIsolationLevel(int level)
      throws SQLException {
!         return level == Connection.TRANSACTION_READ_UNCOMMITTED;
      }
  
      /**
--- 2916,2926 ----
       */
      public boolean supportsTransactionIsolationLevel(int level)
      throws SQLException {
! 
!         return level == Connection.TRANSACTION_READ_UNCOMMITTED
!                || level == Connection.TRANSACTION_READ_COMMITTED
!                || level == Connection.TRANSACTION_REPEATABLE_READ
!                || level == Connection.TRANSACTION_SERIALIZABLE;
      }
  
      /**
*** misc/hsqldb/src/org/hsqldb/jdbc/jdbcPreparedStatement.java	Wed Mar  2 14:50:51 2005
--- misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcPreparedStatement.java	Thu Mar 31 10:35:29 2005
***************
*** 2134,2140 ****
       *
       * @throws SQLException if a database access error occurs
       */
!     public void close() throws SQLException {
  
          if (isClosed()) {
              return;
--- 2134,2140 ----
       *
       * @throws SQLException if a database access error occurs
       */
!     public synchronized void close() throws SQLException {
  
          if (isClosed()) {
              return;
*** misc/hsqldb/src/org/hsqldb/jdbc/jdbcResultSetMetaData.java	Wed Mar  2 14:50:51 2005
--- misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcResultSetMetaData.java	Thu Mar 31 10:35:29 2005
***************
*** 252,266 ****
                      cmd.columnDisplaySize = Types.getMaxDisplaySize(type);
                  } else {
                      cmd.columnDisplaySize = rmd.colSizes[i];
                  }
              } else {
                  cmd.columnDisplaySize = Types.getMaxDisplaySize(type);
              }
  
-             // todo: declared scale (and precision?) across the network
-             // for types that accept (precision, scale) declarations
-             // We do not yet (will we ever?) enforce/consider
-             // NUMERIC/DECIMAL precision
              if (Types.isNumberType(type)
                      && Types.acceptsPrecisionCreateParam(type)) {
                  cmd.precision = rmd.colSizes[i];
--- 252,268 ----
                      cmd.columnDisplaySize = Types.getMaxDisplaySize(type);
                  } else {
                      cmd.columnDisplaySize = rmd.colSizes[i];
+ 
+                     if (Types.acceptsScaleCreateParam(type)) {
+                         if (rmd.colScales[i] != 0) {
+                             cmd.columnDisplaySize += (1 + rmd.colScales[i]);
+                         }
+                     }
                  }
              } else {
                  cmd.columnDisplaySize = Types.getMaxDisplaySize(type);
              }
  
              if (Types.isNumberType(type)
                      && Types.acceptsPrecisionCreateParam(type)) {
                  cmd.precision = rmd.colSizes[i];
*** misc/hsqldb/src/org/hsqldb/jdbc/jdbcStatement.java	Wed Mar  2 14:50:52 2005
--- misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcStatement.java	Thu Mar 31 10:35:29 2005
***************
*** 122,128 ****
   *
   * @author boucherb@users
   * @author fredt@user
!  * @version 1.7.2
   * @see jdbcConnection#createStatement
   * @see jdbcResultSet
   */
--- 122,128 ----
   *
   * @author boucherb@users
   * @author fredt@user
!  * @version 1.8.0
   * @see jdbcConnection#createStatement
   * @see jdbcResultSet
   */
***************
*** 133,139 ****
       * object now explicitly closes all of its open jdbcXXXStatement objects
       * when it is closed.
       */
!     boolean isClosed;
  
      /** Is escape processing enabled? */
      private boolean isEscapeProcessing = true;
--- 133,139 ----
       * object now explicitly closes all of its open jdbcXXXStatement objects
       * when it is closed.
       */
!     volatile boolean isClosed;
  
      /** Is escape processing enabled? */
      private boolean isEscapeProcessing = true;
***************
*** 258,264 ****
       *
       * @exception SQLException if a database access error occurs
       */
!     public void close() throws SQLException {
  
          if (isClosed) {
              return;
--- 258,264 ----
       *
       * @exception SQLException if a database access error occurs
       */
!     public synchronized void close() throws SQLException {
  
          if (isClosed) {
              return;
***************
*** 1533,1539 ****
      /**
       * Retrieves whether this statement is closed.
       */
!     boolean isClosed() {
          return isClosed;
      }
  
--- 1533,1539 ----
      /**
       * Retrieves whether this statement is closed.
       */
!     synchronized boolean isClosed() {
          return isClosed;
      }
  
*** misc/hsqldb/src/org/hsqldb/lib/ArrayUtil.java	Wed Mar  2 14:50:52 2005
--- misc/build/hsqldb/src/org/hsqldb/lib/ArrayUtil.java	Thu Mar 31 10:35:28 2005
***************
*** 788,794 ****
       *  colindex is not copied. If adjust is +1 that element is filled with
       *  the Object addition. All the rest of the elements in source are
       *  shifted left or right accordingly when they are copied. If adjust is 0
!      *  only elements up to colindex are copied.
       *
       *  No checks are perfomed on array sizes and an exception is thrown
       *  if they are not consistent with the other arguments.
--- 788,794 ----
       *  colindex is not copied. If adjust is +1 that element is filled with
       *  the Object addition. All the rest of the elements in source are
       *  shifted left or right accordingly when they are copied. If adjust is 0
!      *  the addition is copied over the element at colindex.
       *
       *  No checks are perfomed on array sizes and an exception is thrown
       *  if they are not consistent with the other arguments.
***************
*** 799,808 ****
  
          int length = Array.getLength(source);
  
          System.arraycopy(source, 0, dest, 0, colindex);
  
          if (adjust == 0) {
!             return;
          } else if (adjust < 0) {
              int endcount = length - colindex - 1;
  
--- 799,821 ----
  
          int length = Array.getLength(source);
  
+         if (colindex < 0) {
+             System.arraycopy(source, 0, dest, 0, length);
+ 
+             return;
+         }
+ 
          System.arraycopy(source, 0, dest, 0, colindex);
  
          if (adjust == 0) {
!             int endcount = length - colindex - 1;
! 
!             Array.set(dest, colindex, addition);
! 
!             if (endcount > 0) {
!                 System.arraycopy(source, colindex + 1, dest, colindex + 1,
!                                  endcount);
!             }
          } else if (adjust < 0) {
              int endcount = length - colindex - 1;
  
***************
*** 917,923 ****
              colindex[i] = i;
          }
      }
!     /*
      public static void main(String[] args) {
  
          int[] a = new int[] {
--- 930,936 ----
              colindex[i] = i;
          }
      }
! /*
      public static void main(String[] args) {
  
          int[] a = new int[] {
*** misc/hsqldb/src/org/hsqldb/lib/HsqlArrayList.java	Wed Mar  2 14:50:52 2005
--- misc/build/hsqldb/src/org/hsqldb/lib/HsqlArrayList.java	Thu Mar 31 10:35:28 2005
***************
*** 331,336 ****
--- 331,340 ----
          Sort.sort(elementData, c, 0, elementCount - 1);
      }
  
+     public Object[] getArray() {
+         return elementData;
+     }
+ 
  // fredt@users - temp - won't need this when start using HashedMappedList for Table
      public void remove(Object obj) {
  
*** misc/hsqldb/src/org/hsqldb/lib/LongKeyIntValueHashMap.java	Thu Mar 31 10:34:36 2005
--- misc/build/hsqldb/src/org/hsqldb/lib/LongKeyIntValueHashMap.java	Thu Mar 31 10:35:29 2005
***************
*** 1 ****
! dummy
--- 1,200 ----
! /* Copyright (c) 2001-2005, The HSQL Development Group
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms, with or without
!  * modification, are permitted provided that the following conditions are met:
!  *
!  * Redistributions of source code must retain the above copyright notice, this
!  * list of conditions and the following disclaimer.
!  *
!  * Redistributions in binary form must reproduce the above copyright notice,
!  * this list of conditions and the following disclaimer in the documentation
!  * and/or other materials provided with the distribution.
!  *
!  * Neither the name of the HSQL Development Group nor the names of its
!  * contributors may be used to endorse or promote products derived from this
!  * software without specific prior written permission.
!  *
!  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
!  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
!  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
!  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
!  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
!  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
!  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
!  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
!  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
!  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
!  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!  */
! 
! 
! package org.hsqldb.lib;
! 
! import java.util.NoSuchElementException;
! 
! import org.hsqldb.store.BaseHashMap;
! 
! /**
!  * @author fredt@users
!  * @version 1.7.2
!  * @since 1.7.2
!  */
! public class LongKeyIntValueHashMap extends BaseHashMap {
! 
!     private Set        keySet;
!     private Collection values;
! 
!     public LongKeyIntValueHashMap() {
!         this(16, 0.75f);
!     }
! 
!     public LongKeyIntValueHashMap(int initialCapacity)
!     throws IllegalArgumentException {
!         this(initialCapacity, 0.75f);
!     }
! 
!     public LongKeyIntValueHashMap(int initialCapacity,
!                                   float loadFactor)
!                                   throws IllegalArgumentException {
!         super(initialCapacity, loadFactor, BaseHashMap.longKeyOrValue,
!               BaseHashMap.intKeyOrValue, false);
!     }
! 
!     public int get(long key) throws NoSuchElementException {
! 
!         int lookup = getLookup(key);
! 
!         if (lookup != -1) {
!             return intValueTable[lookup];
!         }
! 
!         throw new NoSuchElementException();
!     }
! 
!     public int get(long key, int defaultValue) {
! 
!         int lookup = getLookup(key);
! 
!         if (lookup != -1) {
!             return intValueTable[lookup];
!         }
! 
!         return defaultValue;
!     }
! 
!     public boolean get(long key, int[] value) {
! 
!         int lookup = getLookup(key);
! 
!         if (lookup != -1) {
!             value[0] = intValueTable[lookup];
! 
!             return true;
!         }
! 
!         return false;
!     }
! 
!     public boolean put(long key, int value) {
! 
!         int oldSize = size();
! 
!         super.addOrRemove(key, value, null, null, false);
! 
!         return oldSize != size();
!     }
! 
!     public boolean remove(long key) {
! 
!         int oldSize = size();
! 
!         super.addOrRemove(key, 0, null, null, true);
! 
!         return oldSize != size();
!     }
! 
!     public Set keySet() {
! 
!         if (keySet == null) {
!             keySet = new KeySet();
!         }
! 
!         return keySet;
!     }
! 
!     public Collection values() {
! 
!         if (values == null) {
!             values = new Values();
!         }
! 
!         return values;
!     }
! 
!     class KeySet implements Set {
! 
!         public Iterator iterator() {
!             return LongKeyIntValueHashMap.this.new BaseHashIterator(true);
!         }
! 
!         public int size() {
!             return LongKeyIntValueHashMap.this.size();
!         }
! 
!         public boolean contains(Object o) {
!             throw new RuntimeException();
!         }
! 
!         public Object get(Object key) {
!             throw new RuntimeException();
!         }
! 
!         public boolean add(Object value) {
!             throw new RuntimeException();
!         }
! 
!         public boolean remove(Object o) {
!             throw new RuntimeException();
!         }
! 
!         public boolean isEmpty() {
!             return size() == 0;
!         }
! 
!         public void clear() {
!             LongKeyIntValueHashMap.this.clear();
!         }
!     }
! 
!     class Values implements Collection {
! 
!         public Iterator iterator() {
!             return LongKeyIntValueHashMap.this.new BaseHashIterator(false);
!         }
! 
!         public int size() {
!             return LongKeyIntValueHashMap.this.size();
!         }
! 
!         public boolean contains(Object o) {
!             throw new RuntimeException();
!         }
! 
!         public boolean add(Object value) {
!             throw new RuntimeException();
!         }
! 
!         public boolean remove(Object o) {
!             throw new RuntimeException();
!         }
! 
!         public boolean isEmpty() {
!             return size() == 0;
!         }
! 
!         public void clear() {
!             LongKeyIntValueHashMap.this.clear();
!         }
!     }
! }
*** misc/hsqldb/src/org/hsqldb/persist/DataFileCache.java	Wed Mar  2 14:50:53 2005
--- misc/build/hsqldb/src/org/hsqldb/persist/DataFileCache.java	Thu Mar 31 10:35:28 2005
***************
*** 197,206 ****
          fileFreePosition = 0;
  
          try {
!             boolean preexists = false;
              long    freesize  = 0;
  
!             if (fa.isStreamElement(fileName)) {
                  if (database.isStoredFileAccess()) {
                      preexists = true;
                  } else {
--- 197,206 ----
          fileFreePosition = 0;
  
          try {
!             boolean preexists = database.isFilesInJar();
              long    freesize  = 0;
  
!             if (!preexists && fa.isStreamElement(fileName)) {
                  if (database.isStoredFileAccess()) {
                      preexists = true;
                  } else {
***************
*** 234,239 ****
--- 234,243 ----
              int fileType = isNio ? ScaledRAFile.DATA_FILE_NIO
                                   : ScaledRAFile.DATA_FILE_RAF;
  
+             if (database.isFilesInJar()) {
+                 fileType = ScaledRAFile.DATA_FILE_JAR;
+             }
+ 
              // oj@openofice.org - change to file access api
              String cname =
                  database.getURLProperties().getProperty("storage_class_name");
*** misc/hsqldb/src/org/hsqldb/persist/HsqlDatabaseProperties.java	Wed Mar  2 15:04:03 2005
--- misc/build/hsqldb/src/org/hsqldb/persist/HsqlDatabaseProperties.java	Thu Mar 31 10:35:28 2005
***************
*** 145,153 ****
          // char and padding to size and exception if data is too long
          setProperty("sql.enforce_strict_size", false);
  
-         // char and varchar sorting in charset of the current jvm Locale
-         setProperty("sql.compare_in_locale", false);
- 
          // removed from 1.7.2 - sql.month is always true (1-12)
          // removed from 1.7.2 - sql.strict_fk is always enforced
          // if true, requires a pre-existing unique index for foreign key
--- 145,150 ----
***************
*** 254,259 ****
--- 251,257 ----
              setProperty("hsqldb.log_size", 10);
              setProperty("sql.enforce_strict_size", true);
              setProperty("hsqldb.first_identity", 1);
+             setProperty("hsqldb.nio_data_file", false);
          }
  
          setSystemVariables();
***************
*** 262,268 ****
  
      private void setSystemVariables() {
  
!         Column.setCompareInLocal(isPropertyTrue("sql.compare_in_locale"));
  
          Record.gcFrequency = getIntegerProperty("runtime.gc_interval", 0);
      }
--- 260,269 ----
  
      private void setSystemVariables() {
  
!         if (isPropertyTrue("sql.compare_in_locale")) {
!             stringProps.remove("sql.compare_in_locale");
!             database.collation.setCollationAsLocale();
!         }
  
          Record.gcFrequency = getIntegerProperty("runtime.gc_interval", 0);
      }
*** misc/hsqldb/src/org/hsqldb/persist/HsqlProperties.java	Wed Mar  2 14:50:53 2005
--- misc/build/hsqldb/src/org/hsqldb/persist/HsqlProperties.java	Thu Mar 31 10:35:28 2005
***************
*** 392,398 ****
  /*
      public static void main(String[] argv) {
  
!         HsqlProperties props = delimitedArgPairsToProps(
              "filename.cvs;a=123 ;  b=\\delta ;c= another; derrorkey;", "=",
              ";", "textdb");
      }
--- 392,400 ----
  /*
      public static void main(String[] argv) {
  
!         HsqlProperties props1 = delimitedArgPairsToProps("-dbname.0", "=",
!             ";", "server");
!         HsqlProperties props2 = delimitedArgPairsToProps(
              "filename.cvs;a=123 ;  b=\\delta ;c= another; derrorkey;", "=",
              ";", "textdb");
      }
*** misc/hsqldb/src/org/hsqldb/persist/Log.java	Wed Mar  2 14:50:54 2005
--- misc/build/hsqldb/src/org/hsqldb/persist/Log.java	Thu Mar 31 10:35:28 2005
***************
*** 376,385 ****
       */
      DataFileCache getCache() throws HsqlException {
  
          if (database.isFilesInJar()) {
              return null;
          }
! 
          if (cache == null) {
              cache = new DataFileCache(database, cacheFileName,
                                        backupFileName);
--- 376,386 ----
       */
      DataFileCache getCache() throws HsqlException {
  
+ /*
          if (database.isFilesInJar()) {
              return null;
          }
! */
          if (cache == null) {
              cache = new DataFileCache(database, cacheFileName,
                                        backupFileName);
***************
*** 674,681 ****
                  throw (Trace.error(Trace.ACCESS_IS_DENIED, source));
              }
  
!             String path =
!                 new File(new File(fileName).getAbsolutePath()).getParent();
  
              if (path != null) {
                  source = path + File.separator + source;
--- 675,684 ----
                  throw (Trace.error(Trace.ACCESS_IS_DENIED, source));
              }
  
!             String path = new File(
!                 new File(
!                     database.getPath()
!                     + ".properties").getAbsolutePath()).getParent();
  
              if (path != null) {
                  source = path + File.separator + source;
*** misc/hsqldb/src/org/hsqldb/persist/ScaledRAFile.java	Wed Mar  2 14:50:54 2005
--- misc/build/hsqldb/src/org/hsqldb/persist/ScaledRAFile.java	Thu Mar 31 10:35:28 2005
***************
*** 55,60 ****
--- 55,61 ----
  
      static final int         DATA_FILE_RAF = 0;
      static final int         DATA_FILE_NIO = 1;
+     static final int         DATA_FILE_JAR = 2;
      final RandomAccessFile   file;
      private final boolean    readOnly;
      final String             fileName;
***************
*** 101,107 ****
              }
          }
  
!         if (type == DATA_FILE_RAF) {
              return new ScaledRAFile(name, readonly);
          } else {
              try {
--- 102,110 ----
              }
          }
  
!         if (type == DATA_FILE_JAR) {
!             return new ScaledRAFileInJar(name);
!         } else if (type == DATA_FILE_RAF) {
              return new ScaledRAFile(name, readonly);
          } else {
              try {
***************
*** 248,254 ****
              cacheHit++;
          }
  
- // 1_8_0_n
          ba.reset();
          ba.skip(seekPosition - bufferOffset);
  
--- 251,256 ----
*** misc/hsqldb/src/org/hsqldb/persist/ScaledRAFileInJar.java	Thu Mar 31 10:34:36 2005
--- misc/build/hsqldb/src/org/hsqldb/persist/ScaledRAFileInJar.java	Thu Mar 31 10:35:28 2005
***************
*** 1 ****
! dummy
--- 1,234 ----
! /* Copyright (c) 2001-2005, The HSQL Development Group
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms, with or without
!  * modification, are permitted provided that the following conditions are met:
!  *
!  * Redistributions of source code must retain the above copyright notice, this
!  * list of conditions and the following disclaimer.
!  *
!  * Redistributions in binary form must reproduce the above copyright notice,
!  * this list of conditions and the following disclaimer in the documentation
!  * and/or other materials provided with the distribution.
!  *
!  * Neither the name of the HSQL Development Group nor the names of its
!  * contributors may be used to endorse or promote products derived from this
!  * software without specific prior written permission.
!  *
!  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
!  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
!  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
!  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
!  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
!  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
!  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
!  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
!  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
!  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
!  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!  */
! 
! 
! package org.hsqldb.persist;
! 
! import java.io.FileNotFoundException;
! import java.io.IOException;
! import java.io.DataInputStream;
! import java.io.InputStream;
! 
! import org.hsqldb.lib.HsqlByteArrayInputStream;
! import org.hsqldb.lib.Storage;
! 
! /**
!  * This class is a random access wrapper around a DataInputStream object and
!  * enables access to cached tables when a database is included in a jar.
!  *
!  * A proof-of-concept prototype was first contributed by winfriedthom@users.
!  *
!  * @author fredt@users
!  * @version  1.8.0
!  * @since  1.8.0
!  */
! class ScaledRAFileInJar implements Storage {
! 
!     DataInputStream          file;
!     final String             fileName;
!     long                     fileLength;
!     boolean                  bufferDirty = true;
!     byte[]                   buffer      = new byte[4096];
!     HsqlByteArrayInputStream ba = new HsqlByteArrayInputStream(buffer);
!     long                     bufferOffset;
! 
!     //
!     long seekPosition;
!     long realPosition;
! 
!     ScaledRAFileInJar(String name) throws FileNotFoundException, IOException {
! 
!         fileName = name;
! 
!         resetStream();
!         file.skip(DataFileCache.LONG_FREE_POS_POS);
! 
!         fileLength = file.readLong();
! 
!         resetStream();
!     }
! 
!     public long length() throws IOException {
!         return fileLength;
!     }
! 
!     /**
!      * Some JVM's do not allow seek beyond end of file, so zeros are written
!      * first in that case. Reported by bohgammer@users in Open Disucssion
!      * Forum.
!      */
!     public void seek(long position) throws IOException {
!         seekPosition = position;
!     }
! 
!     public long getFilePointer() throws IOException {
!         return seekPosition;
!     }
! 
!     private void readIntoBuffer() throws IOException {
! 
!         long filePos = seekPosition;
! 
!         bufferDirty = false;
! 
!         long subOffset  = filePos % buffer.length;
!         long readLength = fileLength - (filePos - subOffset);
! 
!         if (readLength <= 0) {
!             throw new IOException("read beyond end of file");
!         }
! 
!         if (readLength > buffer.length) {
!             readLength = buffer.length;
!         }
! 
!         fileSeek(filePos - subOffset);
!         file.readFully(buffer, 0, (int) readLength);
! 
!         bufferOffset = filePos - subOffset;
!         realPosition = bufferOffset + readLength;
!     }
! 
!     public int read() throws IOException {
! 
!         if (seekPosition >= fileLength) {
!             return -1;
!         }
! 
!         if (bufferDirty || seekPosition < bufferOffset
!                 || seekPosition >= bufferOffset + buffer.length) {
!             readIntoBuffer();
!         }
! 
!         ba.reset();
!         ba.skip(seekPosition - bufferOffset);
! 
!         int val = ba.read();
! 
!         seekPosition++;
! 
!         return val;
!     }
! 
!     public long readLong() throws IOException {
! 
!         long hi = readInt();
!         long lo = readInt();
! 
!         return (hi << 32) + (lo & 0xffffffffL);
!     }
! 
!     public int readInt() throws IOException {
! 
!         if (bufferDirty || seekPosition < bufferOffset
!                 || seekPosition >= bufferOffset + buffer.length) {
!             readIntoBuffer();
!         }
! 
!         ba.reset();
!         ba.skip(seekPosition - bufferOffset);
! 
!         int val = ba.readInt();
! 
!         seekPosition += 4;
! 
!         return val;
!     }
! 
!     public void read(byte[] b, int offset, int length) throws IOException {
! 
!         if (bufferDirty || seekPosition < bufferOffset
!                 || seekPosition >= bufferOffset + buffer.length) {
!             readIntoBuffer();
!         }
! 
!         ba.reset();
!         ba.skip(seekPosition - bufferOffset);
! 
!         int bytesRead = ba.read(b, offset, length);
! 
!         seekPosition += bytesRead;
! 
!         if (bytesRead < length) {
!             if (seekPosition != realPosition) {
!                 fileSeek(seekPosition);
!             }
! 
!             file.readFully(b, offset + bytesRead, length - bytesRead);
! 
!             seekPosition += (length - bytesRead);
!             realPosition = seekPosition;
!         }
!     }
! 
!     public void write(byte[] b, int off, int len) throws IOException {}
! 
!     public void writeInt(int i) throws IOException {}
! 
!     public void writeLong(long i) throws IOException {}
! 
!     public void close() throws IOException {
!         file.close();
!     }
! 
!     public boolean isReadOnly() {
!         return true;
!     }
! 
!     public boolean wasNio() {
!         return false;
!     }
! 
!     private void resetStream() throws IOException {
! 
!         if (file != null) {
!             file.close();
!         }
! 
!         InputStream fis = getClass().getResourceAsStream(fileName);
! 
!         file = new DataInputStream(fis);
!     }
! 
!     private void fileSeek(long position) throws IOException {
! 
!         long skipPosition = realPosition;
! 
!         if (position < skipPosition) {
!             resetStream();
! 
!             skipPosition = 0;
!         }
! 
!         while (position > skipPosition) {
!             skipPosition += file.skip(position - skipPosition);
!         }
!     }
! }
*** misc/hsqldb/src/org/hsqldb/rowio/RowOutputTextLog.java	Wed Mar  2 14:50:54 2005
--- misc/build/hsqldb/src/org/hsqldb/rowio/RowOutputTextLog.java	Thu Mar 31 10:35:28 2005
***************
*** 39,44 ****
--- 39,45 ----
  
  import org.hsqldb.CachedRow;
  import org.hsqldb.Column;
+ import org.hsqldb.HsqlDateTime;
  import org.hsqldb.HsqlException;
  import org.hsqldb.lib.StringConverter;
  import org.hsqldb.types.Binary;
***************
*** 188,194 ****
      protected void writeTimestamp(Timestamp o) {
  
          write('\'');
!         this.writeBytes(o.toString());
          write('\'');
      }
  
--- 189,195 ----
      protected void writeTimestamp(Timestamp o) {
  
          write('\'');
!         this.writeBytes(HsqlDateTime.getTimestampString(o, null));
          write('\'');
      }
  
*** misc/hsqldb/src/org/hsqldb/scriptio/ScriptWriterBase.java	Wed Mar  2 14:50:54 2005
--- misc/build/hsqldb/src/org/hsqldb/scriptio/ScriptWriterBase.java	Thu Mar 31 10:35:28 2005
***************
*** 41,46 ****
--- 41,47 ----
  import org.hsqldb.DatabaseScript;
  import org.hsqldb.HsqlException;
  import org.hsqldb.Result;
+ import org.hsqldb.Session;
  import org.hsqldb.Table;
  import org.hsqldb.Token;
  import org.hsqldb.Trace;
***************
*** 83,89 ****
  // used at checkpoint
  public abstract class ScriptWriterBase implements Runnable {
  
!     Database            db;
      String              outFile;
      OutputStream        fileStreamOut;
      FileAccess.FileSync outDescriptor;
--- 84,90 ----
  // used at checkpoint
  public abstract class ScriptWriterBase implements Runnable {
  
!     Database            database;
      String              outFile;
      OutputStream        fileStreamOut;
      FileAccess.FileSync outDescriptor;
***************
*** 139,145 ****
              throw Trace.error(Trace.FILE_IO_ERROR, file);
          }
  
!         this.db                = db;
          this.includeCachedData = includeCachedData;
          outFile                = file;
  
--- 140,146 ----
              throw Trace.error(Trace.FILE_IO_ERROR, file);
          }
  
!         this.database          = db;
          this.includeCachedData = includeCachedData;
          outFile                = file;
  
***************
*** 219,225 ****
      protected void openFile() throws HsqlException {
  
          try {
!             FileAccess   fa  = db.getFileAccess();
              OutputStream fos = fa.openOutputStreamElement(outFile);
  
              outDescriptor = fa.getFileSync(fos);
--- 220,226 ----
      protected void openFile() throws HsqlException {
  
          try {
!             FileAccess   fa  = database.getFileAccess();
              OutputStream fos = fa.openOutputStreamElement(outFile);
  
              outDescriptor = fa.getFileSync(fos);
***************
*** 240,253 ****
  
      protected void writeDDL() throws IOException, HsqlException {
  
!         Result ddlPart = DatabaseScript.getScript(db, !includeCachedData);
  
          writeSingleColumnResult(ddlPart);
      }
  
      protected void writeExistingData() throws HsqlException, IOException {
  
!         HsqlArrayList tables = db.getTables();
  
          for (int i = 0, size = tables.size(); i < size; i++) {
              Table t = (Table) tables.get(i);
--- 241,256 ----
  
      protected void writeDDL() throws IOException, HsqlException {
  
!         Result ddlPart = DatabaseScript.getScript(database,
!             !includeCachedData);
  
          writeSingleColumnResult(ddlPart);
      }
  
      protected void writeExistingData() throws HsqlException, IOException {
  
!         HsqlArrayList tables  = database.getTables();
!         Session       session = database.sessionManager.getSysSession();
  
          for (int i = 0, size = tables.size(); i < size; i++) {
              Table t = (Table) tables.get(i);
***************
*** 277,283 ****
                  if (script) {
                      writeTableInit(t);
  
!                     RowIterator it = t.rowIterator(null);
  
                      while (it.hasNext()) {
                          writeRow(0, t, it.next().getData());
--- 280,286 ----
                  if (script) {
                      writeTableInit(t);
  
!                     RowIterator it = t.rowIterator(session);
  
                      while (it.hasNext()) {
                          writeRow(0, t, it.next().getData());
*** misc/hsqldb/src/org/hsqldb/scriptio/ScriptWriterZipped.java	Wed Mar  2 14:50:54 2005
--- misc/build/hsqldb/src/org/hsqldb/scriptio/ScriptWriterZipped.java	Thu Mar 31 10:35:28 2005
***************
*** 63,69 ****
      protected void openFile() throws HsqlException {
  
          try {
!             FileAccess           fa  = db.getFileAccess();
              java.io.OutputStream fos = fa.openOutputStreamElement(outFile);
  
              outDescriptor = fa.getFileSync(fos);
--- 63,69 ----
      protected void openFile() throws HsqlException {
  
          try {
!             FileAccess           fa  = database.getFileAccess();
              java.io.OutputStream fos = fa.openOutputStreamElement(outFile);
  
              outDescriptor = fa.getFileSync(fos);
*** misc/hsqldb/src/org/hsqldb/test/TestBase.java	Wed Mar  2 14:50:56 2005
--- misc/build/hsqldb/src/org/hsqldb/test/TestBase.java	Thu Mar 31 10:35:28 2005
***************
*** 48,60 ****
  public abstract class TestBase extends TestCase {
  
      //  change the url to reflect your preferred db location and name
-     //  String url = "jdbc:hsqldb:hsql://localhost/yourtest";
      String  serverProps;
      String  url;
      String  user     = "sa";
      String  password = "";
      Server  server;
!     boolean isNetwork = false;
  
      public TestBase(String name) {
          super(name);
--- 48,59 ----
  public abstract class TestBase extends TestCase {
  
      //  change the url to reflect your preferred db location and name
      String  serverProps;
      String  url;
      String  user     = "sa";
      String  password = "";
      Server  server;
!     boolean isNetwork = true;
  
      public TestBase(String name) {
          super(name);
*** misc/hsqldb/src/org/hsqldb/test/TestBug785429.java	Wed Mar  2 14:50:56 2005
--- misc/build/hsqldb/src/org/hsqldb/test/TestBug785429.java	Thu Mar 31 10:35:28 2005
***************
*** 55,61 ****
  
      public void test() throws Exception {
  
!         Connection        conn = newConnection();
          Statement         stmt = conn.createStatement();
          String            sql;
          String            msg;
--- 55,64 ----
  
      public void test() throws Exception {
  
!         Connection conn = newConnection();
! 
!         conn.setAutoCommit(false);
! 
          Statement         stmt = conn.createStatement();
          String            sql;
          String            msg;
*** misc/hsqldb/src/org/hsqldb/test/TestCacheSize.java	Wed Mar  2 14:50:56 2005
--- misc/build/hsqldb/src/org/hsqldb/test/TestCacheSize.java	Thu Mar 31 10:35:28 2005
***************
*** 107,116 ****
      int     deleteWhileInsertInterval = 10000;
  
      // size of the tables used in test
!     int bigrows = 256000;
  
      // number of ops
!     int bigops    = 256000;
      int smallops  = 8000;
      int smallrows = 0xfff;
  
--- 107,116 ----
      int     deleteWhileInsertInterval = 10000;
  
      // size of the tables used in test
!     int bigrows = 64000;
  
      // number of ops
!     int bigops    = 64000;
      int smallops  = 8000;
      int smallrows = 0xfff;
  
*** misc/hsqldb/src/org/hsqldb/test/TestCollation.java	Thu Mar 31 10:34:36 2005
--- misc/build/hsqldb/src/org/hsqldb/test/TestCollation.java	Thu Mar 31 10:35:28 2005
***************
*** 1 ****
! dummy
--- 1,270 ----
! /* Copyright (c) 2001-2005, The HSQL Development Group
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms, with or without
!  * modification, are permitted provided that the following conditions are met:
!  *
!  * Redistributions of source code must retain the above copyright notice, this
!  * list of conditions and the following disclaimer.
!  *
!  * Redistributions in binary form must reproduce the above copyright notice,
!  * this list of conditions and the following disclaimer in the documentation
!  * and/or other materials provided with the distribution.
!  *
!  * Neither the name of the HSQL Development Group nor the names of its
!  * contributors may be used to endorse or promote products derived from this
!  * software without specific prior written permission.
!  *
!  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
!  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
!  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
!  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
!  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
!  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
!  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
!  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
!  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
!  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
!  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!  */
! 
! 
! package org.hsqldb.test;
! 
! import junit.framework.TestCase;
! import junit.framework.TestResult;
! 
! /**
!  * Test HSQLDBs collation capabilities
!  * @author frank.schoenheit@sun.com
!  */
! public class TestCollation extends TestBase {
! 
!     java.sql.Statement      statement;
!     java.sql.Connection     connection;
!     org.hsqldb.Collation    collation;
!     org.hsqldb.lib.Iterator collIterator;
!     org.hsqldb.lib.Iterator localeIterator;
! 
!     /** Creates a new instance of TestCollation */
!     public TestCollation(String name) {
! 
!         super(name);
! 
!         super.isNetwork = false;
!     }
! 
!     protected void setUp() {
! 
!         super.setUp();
! 
!         try {
!             connection = super.newConnection();
!             statement  = connection.createStatement();
!         } catch (Exception e) {}
! 
!         collation      = new org.hsqldb.Collation();
!         collIterator   = collation.getCollationsIterator();
!         localeIterator = collation.getLocalesIterator();
!     }
! 
!     protected void tearDown() {
! 
!         try {
!             statement = connection.createStatement();
! 
!             statement.execute("SHUTDOWN");
!         } catch (Exception e) {}
! 
!         super.tearDown();
!     }
! 
!     /**
!      * checks whether expected locales are present and selectable
!      */
!     public void verifyAvailability() {
! 
!         // let's check whether unknown collation identifiers are rejected
!         try {
!             statement.execute(
!                 getSetCollationStmt(
!                     "ThisIsDefinatelyNoValidCollationIdentifier"));
!             fail("database did not reject invalid collation name");
!         } catch (java.sql.SQLException e) {}
! 
!         // let's check whether the DB accepts all known collations
!         int count = 0;
! 
!         while (collIterator.hasNext()) {
!             String collationName = (String) collIterator.next();
! 
!             try {
!                 statement.execute(getSetCollationStmt(collationName));
!             } catch (java.sql.SQLException e) {
!                 fail("could not set collation '" + collationName
!                      + "'\n  exception message: " + e.getMessage());
!             }
! 
!             ++count;
!         }
! 
!         System.out.println("checked " + count
!                            + " collations for availability.");
! 
!         // even if the above worked, we cannot be sure that all locales are really supported.
!         // The fact that SET DATABASE COLLATION succeeeded only means that a Collator could
!         // be instantiated with a Locale matching the given collation name. But what if
!         // Locale.Instance(...) lied, and returned a fallback Locale instance?
!         //
!         // Hmm, looking at the documentation of Locale.getAvailableLocales, I'm not sure
!         // whether it is really feasible. The doc states "returns a list of all installed Locales".
!         // The "installed" puzzles me - maybe this is really different per installation, and not only
!         // per JDK version?
!         java.util.Locale availableLocales[] =
!             java.util.Locale.getAvailableLocales();
!         org.hsqldb.lib.Set existenceCheck = new org.hsqldb.lib.HashSet();
! 
!         for (int i = 0; i < availableLocales.length; ++i) {
!             String availaleName = availableLocales[i].getLanguage();
! 
!             if (availableLocales[i].getCountry().length() > 0) {
!                 availaleName += "-" + availableLocales[i].getCountry();
!             }
! 
!             existenceCheck.add(availaleName);
!         }
! 
!         String notInstalled = "";
!         int    expected     = 0,
!                failed       = 0;
! 
!         while (localeIterator.hasNext()) {
!             String localeName = (String) localeIterator.next();
! 
!             ++expected;
! 
!             if (!existenceCheck.contains(localeName)) {
!                 if (notInstalled.length() > 0) {
!                     notInstalled += "; ";
!                 }
! 
!                 notInstalled += localeName;
! 
!                 ++failed;
!             }
!         }
! 
!         if (notInstalled.length() > 0) {
!             fail("the following locales are not installed:\n  "
!                  + notInstalled + "\n  (" + failed + " out of " + expected
!                  + ")");
!         }
!     }
! 
!     /**
!      * checks whether sorting via a given collation works as expected
!      */
!     public void verifyCollation() {
! 
!         String failedCollations = "";
!         String failMessage      = "";
! 
!         while (collIterator.hasNext()) {
!             String collationName = (String) collIterator.next();
!             String message       = checkSorting(collationName);
! 
!             if (message.length() > 0) {
!                 if (failedCollations.length() > 0) {
!                     failedCollations += ", ";
!                 }
! 
!                 failedCollations += collationName;
!                 failMessage      += message;
!             }
!         }
! 
!         if (failedCollations.length() > 0) {
!             fail("test failed for following collations:\n" + failedCollations
!                  + "\n" + failMessage);
!         }
!     }
! 
!     /**
!      * returns an SQL statement to set the database collation
!      */
!     protected final String getSetCollationStmt(String collationName) {
! 
!         final String setCollationStmtPre  = "SET DATABASE COLLATION \"";
!         final String setCollationStmtPost = "\"";
! 
!         return setCollationStmtPre + collationName + setCollationStmtPost;
!     }
! 
!     /**
!      * checks sorting a table with according to a given collation
!      */
!     protected String checkSorting(String collationName) {
! 
!         String prepareStmt =
!             "DROP TABLE WORDLIST IF EXISTS;"
!             + "CREATE TEXT TABLE WORDLIST ( ID INTEGER, WORD VARCHAR );"
!             + "SET TABLE WORDLIST SOURCE \"" + collationName
!             + ".csv;encoding=UTF-8\"";
!         String selectStmt    = "SELECT ID, WORD FROM WORDLIST ORDER BY WORD";
!         String returnMessage = "";
! 
!         try {
! 
!             // set database collation
!             statement.execute(getSetCollationStmt(collationName));
!             statement.execute(prepareStmt);
! 
!             java.sql.ResultSet results = statement.executeQuery(selectStmt);
! 
!             while (results.next()) {
!                 int expectedPosition = results.getInt(1);
!                 int foundPosition    = results.getRow();
! 
!                 if (expectedPosition != foundPosition) {
!                     String word = results.getString(2);
! 
!                     return "testing collation '" + collationName
!                            + "' failed\n" + "  word              : " + word
!                            + "\n" + "  expected position : "
!                            + expectedPosition + "\n"
!                            + "  found position    : " + foundPosition + "\n";
!                 }
!             }
!         } catch (java.sql.SQLException e) {
!             return "testing collation '" + collationName
!                    + "' failed\n  exception message: " + e.getMessage()
!                    + "\n";
!         }
! 
!         return "";
!     }
! 
!     public static void main(String[] argv) {
! 
!         TestResult result       = new TestResult();
!         TestCase   availability = new TestCollation("verifyAvailability");
! 
!         availability.run(result);
! 
!         TestCase sorting = new TestCollation("verifyCollation");
! 
!         sorting.run(result);
! 
!         if (result.failureCount() != 0) {
!             System.err.println("TestCollation encountered errors:");
! 
!             java.util.Enumeration failures = result.failures();
! 
!             while (failures.hasMoreElements()) {
!                 System.err.println(failures.nextElement().toString());
!             }
!         } else {
!             System.out.println("TestCollation: all fine.");
!         }
!     }
! }
*** misc/hsqldb/src/org/hsqldb/test/TestDatabaseMetaData.java	Wed Mar  2 14:50:56 2005
--- misc/build/hsqldb/src/org/hsqldb/test/TestDatabaseMetaData.java	Thu Mar 31 10:35:28 2005
***************
*** 189,195 ****
              int               c  = md.getScale(1);
              int               d  = md.getScale(2);
              String            e  = md.getColumnClassName(10);
!             boolean testresult = (x == y) && (x == 10) && (b == 10)
                                   && (c == 0) && (d == 2)
                                   && e.equals("java.sql.Timestamp");
  
--- 189,195 ----
              int               c  = md.getScale(1);
              int               d  = md.getScale(2);
              String            e  = md.getColumnClassName(10);
!             boolean testresult = (x == 10) && (y == 13) && (b == 10)
                                   && (c == 0) && (d == 2)
                                   && e.equals("java.sql.Timestamp");
  
*** misc/hsqldb/src/org/hsqldb/test/TestHashStructures.java	Wed Mar  2 14:50:57 2005
--- misc/build/hsqldb/src/org/hsqldb/test/TestHashStructures.java	Thu Mar 31 10:35:28 2005
***************
*** 32,38 ****
  package org.hsqldb.test;
  
  import java.util.Random;
- import java.util.Arrays;
  
  import org.hsqldb.lib.DoubleIntIndex;
  
--- 32,37 ----
***************
*** 53,175 ****
  
      public void testHashMap() throws Exception {
  
          int                    testSize = 33;
          org.hsqldb.lib.HashMap hMap     = new org.hsqldb.lib.HashMap();
          org.hsqldb.lib.IntKeyHashMap hIntMap =
              new org.hsqldb.lib.IntKeyHashMap();
          java.util.HashMap uMap = new java.util.HashMap();
  
!         // -
!         populateBySerialIntKeys(uMap, hMap, testSize);
!         compareByUIterator(uMap, hMap);
!         compareByHIterator(uMap, hMap);
! 
!         // -
!         populateByRandomIntKeys(uMap, hMap, testSize);
!         compareByUIterator(uMap, hMap);
!         compareByHIterator(uMap, hMap);
! 
!         //
!         depopulateRandomly(uMap, hMap, 20);
!         compareByUIterator(uMap, hMap);
!         compareByHIterator(uMap, hMap);
! 
!         // -
!         populateBySerialIntKeys(uMap, hMap, testSize);
!         compareByUIterator(uMap, hMap);
!         compareByHIterator(uMap, hMap);
! 
!         //
!         depopulateByIterator(uMap, hMap, 20);
!         compareByUIterator(uMap, hMap);
!         compareByHIterator(uMap, hMap);
      }
  
      public void testIntKeyHashMap() throws Exception {
  
!         int testSize = 33;
          org.hsqldb.lib.IntKeyHashMap hIntMap =
              new org.hsqldb.lib.IntKeyHashMap();
          java.util.HashMap uMap = new java.util.HashMap();
  
!         populateBySerialIntKeysInt(uMap, hIntMap, testSize);
!         compareByUIteratorInt(uMap, hIntMap);
!         populateByRandomIntKeysInt(uMap, hIntMap, testSize);
!         compareByUIteratorInt(uMap, hIntMap);
!         compareByHIteratorInt(uMap, hIntMap);
! 
!         //
!         depopulateByIntIterator(uMap, hIntMap, 20);
!         compareByUIteratorInt(uMap, hIntMap);
!         compareByHIteratorInt(uMap, hIntMap);
! 
!         //
!         clearByIntIterator(uMap, hIntMap);
!         compareByUIteratorInt(uMap, hIntMap);
!         compareByHIteratorInt(uMap, hIntMap);
! 
!         // -
!         populateBySerialIntKeysInt(uMap, hIntMap, testSize);
!         compareByUIteratorInt(uMap, hIntMap);
!         compareByHIteratorInt(uMap, hIntMap);
! 
!         //
!         clearByIntIterator(uMap, hIntMap);
!         compareByUIteratorInt(uMap, hIntMap);
!         compareByHIteratorInt(uMap, hIntMap);
  
!         //-
!         assertTrue(true);
      }
  
      public void testHashMappedList() throws Exception {
  
!         int testSize = 33;
          org.hsqldb.lib.HashMappedList hMap =
              new org.hsqldb.lib.HashMappedList();
          java.util.HashMap uMap = new java.util.HashMap();
  
!         populateBySerialIntKeys(uMap, hMap, testSize);
!         compareByUIterator(uMap, hMap);
!         compareByHIterator(uMap, hMap);
!         populateByRandomIntKeys(uMap, hMap, testSize);
!         compareByUIterator(uMap, hMap);
!         compareByHIterator(uMap, hMap);
!         depopulateRandomly(uMap, hMap, 20);
!         compareByUIterator(uMap, hMap);
!         compareByHIterator(uMap, hMap);
!         populateByRandomIntKeys(uMap, hMap, testSize);
!         compareByUIterator(uMap, hMap);
!         compareByHIterator(uMap, hMap);
!         depopulateRandomly(uMap, hMap, 20);
!         populateBySerialIntKeys(uMap, hMap, testSize);
!         compareByUIterator(uMap, hMap);
!         compareByHIterator(uMap, hMap);
  
!         //-
!         assertTrue(true);
      }
  
      public void testDoubleIntLookup() throws Exception {
  
!         int testSize = 512;
          org.hsqldb.lib.IntKeyHashMap hIntMap =
              new org.hsqldb.lib.IntKeyHashMap();
          DoubleIntIndex intLookup = new DoubleIntIndex(12, false);
  
!         intLookup.setKeysSearchTarget();
!         populateBySerialIntKeysInt(intLookup, hIntMap, testSize);
!         compareByHIteratorInt(intLookup, hIntMap);
!         populateByRandomIntKeysInt(intLookup, hIntMap, testSize);
!         compareByHIteratorInt(intLookup, hIntMap);
  
!         //-
!         assertTrue(true);
      }
  
      public void testDoubleIntSpeed() throws Exception {
  
!         int testSize = 500;
          org.hsqldb.lib.IntKeyHashMap hIntMap =
              new org.hsqldb.lib.IntKeyHashMap();
          DoubleIntIndex intLookup = new DoubleIntIndex(testSize, false);
--- 52,193 ----
  
      public void testHashMap() throws Exception {
  
+         boolean                failed   = false;
          int                    testSize = 33;
          org.hsqldb.lib.HashMap hMap     = new org.hsqldb.lib.HashMap();
          org.hsqldb.lib.IntKeyHashMap hIntMap =
              new org.hsqldb.lib.IntKeyHashMap();
          java.util.HashMap uMap = new java.util.HashMap();
  
!         try {
!             populateBySerialIntKeys(uMap, hMap, testSize);
!             compareByUIterator(uMap, hMap);
!             compareByHIterator(uMap, hMap);
! 
!             // -
!             populateByRandomIntKeys(uMap, hMap, testSize);
!             compareByUIterator(uMap, hMap);
!             compareByHIterator(uMap, hMap);
! 
!             //
!             depopulateRandomly(uMap, hMap, 20);
!             compareByUIterator(uMap, hMap);
!             compareByHIterator(uMap, hMap);
! 
!             // -
!             populateBySerialIntKeys(uMap, hMap, testSize);
!             compareByUIterator(uMap, hMap);
!             compareByHIterator(uMap, hMap);
! 
!             //
!             depopulateByIterator(uMap, hMap, 20);
!             compareByUIterator(uMap, hMap);
!             compareByHIterator(uMap, hMap);
!         } catch (Exception e) {
!             failed = true;
!         }
! 
!         assertTrue(!failed);
      }
  
      public void testIntKeyHashMap() throws Exception {
  
!         boolean failed   = false;
!         int     testSize = 33;
          org.hsqldb.lib.IntKeyHashMap hIntMap =
              new org.hsqldb.lib.IntKeyHashMap();
          java.util.HashMap uMap = new java.util.HashMap();
  
!         try {
!             populateBySerialIntKeysInt(uMap, hIntMap, testSize);
!             compareByUIteratorInt(uMap, hIntMap);
!             populateByRandomIntKeysInt(uMap, hIntMap, testSize);
!             compareByUIteratorInt(uMap, hIntMap);
!             compareByHIteratorInt(uMap, hIntMap);
! 
!             //
!             depopulateByIntIterator(uMap, hIntMap, 20);
!             compareByUIteratorInt(uMap, hIntMap);
!             compareByHIteratorInt(uMap, hIntMap);
! 
!             //
!             clearByIntIterator(uMap, hIntMap);
!             compareByUIteratorInt(uMap, hIntMap);
!             compareByHIteratorInt(uMap, hIntMap);
! 
!             // -
!             populateBySerialIntKeysInt(uMap, hIntMap, testSize);
!             compareByUIteratorInt(uMap, hIntMap);
!             compareByHIteratorInt(uMap, hIntMap);
! 
!             //
!             clearByIntIterator(uMap, hIntMap);
!             compareByUIteratorInt(uMap, hIntMap);
!             compareByHIteratorInt(uMap, hIntMap);
!         } catch (Exception e) {
!             failed = true;
!         }
  
!         assertTrue(!failed);
      }
  
      public void testHashMappedList() throws Exception {
  
!         boolean failed   = false;
!         int     testSize = 33;
          org.hsqldb.lib.HashMappedList hMap =
              new org.hsqldb.lib.HashMappedList();
          java.util.HashMap uMap = new java.util.HashMap();
  
!         try {
!             populateBySerialIntKeys(uMap, hMap, testSize);
!             compareByUIterator(uMap, hMap);
!             compareByHIterator(uMap, hMap);
!             populateByRandomIntKeys(uMap, hMap, testSize);
!             compareByUIterator(uMap, hMap);
!             compareByHIterator(uMap, hMap);
!             depopulateRandomly(uMap, hMap, 20);
!             compareByUIterator(uMap, hMap);
!             compareByHIterator(uMap, hMap);
!             populateByRandomIntKeys(uMap, hMap, testSize);
!             compareByUIterator(uMap, hMap);
!             compareByHIterator(uMap, hMap);
!             depopulateRandomly(uMap, hMap, 20);
!             populateBySerialIntKeys(uMap, hMap, testSize);
!             compareByUIterator(uMap, hMap);
!             compareByHIterator(uMap, hMap);
!         } catch (Exception e) {
!             failed = true;
!         }
  
!         assertTrue(!failed);
      }
  
      public void testDoubleIntLookup() throws Exception {
  
!         boolean failed   = false;
!         int     testSize = 512;
          org.hsqldb.lib.IntKeyHashMap hIntMap =
              new org.hsqldb.lib.IntKeyHashMap();
          DoubleIntIndex intLookup = new DoubleIntIndex(12, false);
  
!         try {
!             intLookup.setKeysSearchTarget();
!             populateBySerialIntKeysInt(intLookup, hIntMap, testSize);
!             compareByHIteratorInt(intLookup, hIntMap);
!             populateByRandomIntKeysInt(intLookup, hIntMap, testSize);
!             compareByHIteratorInt(intLookup, hIntMap);
!         } catch (Exception e) {
!             failed = true;
!         }
  
!         assertTrue(!failed);
      }
  
      public void testDoubleIntSpeed() throws Exception {
  
!         boolean failed   = false;
!         int     testSize = 500;
          org.hsqldb.lib.IntKeyHashMap hIntMap =
              new org.hsqldb.lib.IntKeyHashMap();
          DoubleIntIndex intLookup = new DoubleIntIndex(testSize, false);
***************
*** 207,216 ****
              System.out.println(
                  sw.elapsedTimeToMessage("Double int table error: i =" + i));
  
!             throw e;
          }
  
!         assertTrue(true);
      }
  
      int[] getSampleIntArray(org.hsqldb.lib.DoubleIntIndex index, int size) {
--- 225,234 ----
              System.out.println(
                  sw.elapsedTimeToMessage("Double int table error: i =" + i));
  
!             failed = true;
          }
  
!         assertTrue(!failed);
      }
  
      int[] getSampleIntArray(org.hsqldb.lib.DoubleIntIndex index, int size) {
*** misc/hsqldb/src/org/hsqldb/test/TestScript.java	Wed Mar  2 14:50:57 2005
--- misc/build/hsqldb/src/org/hsqldb/test/TestScript.java	Thu Mar 31 10:35:28 2005
***************
*** 36,48 ****
  
  public class TestScript extends TestBase {
  
!     String path = "TestSelfConstraints.txt";
! 
  //    String path = "TestSelfFieldLimits.txt";
  //    String path = "TestSelfLeftJoin.txt";
  //    String path = "TestSelfQueries.txt";
! //    String path = "TestSelfCheckConstraints.txt";
! //    String path = "TestSelfLeftJoin.txt";
      public TestScript(String name) {
          super(name);
      }
--- 36,53 ----
  
  public class TestScript extends TestBase {
  
! //    String path = "TestSelfCaseWhen.txt";
! //    String path = "TestSelfCheckConstraints.txt";
! //    String path = "TestSelfConstraints.txt";
  //    String path = "TestSelfFieldLimits.txt";
  //    String path = "TestSelfLeftJoin.txt";
+ //    String path = "TestSelfNameResolution.txt";
+ //    String path = "TestSelfInPredicateReferencing.txt";
  //    String path = "TestSelfQueries.txt";
! //    String path = "TestSelfUnions.txt";
! //    String path = "TestSelfUserFunction.txt";
!     String path = "TestTemp.txt";
! 
      public TestScript(String name) {
          super(name);
      }
***************
*** 50,57 ****
      public void test() throws java.lang.Exception {
  
          Connection conn = newConnection();
-         Statement  stmt = conn.createStatement();
  
          TestUtil.testScript(conn, path);
      }
  }
--- 55,68 ----
      public void test() throws java.lang.Exception {
  
          Connection conn = newConnection();
  
          TestUtil.testScript(conn, path);
      }
+ 
+     public static void main(String[] Args) throws Exception {
+ 
+         TestScript ts = new TestScript("test");
+ 
+         ts.test();
+     }
  }
*** misc/hsqldb/src/org/hsqldb/test/TestUtil.java	Wed Mar  2 14:50:57 2005
--- misc/build/hsqldb/src/org/hsqldb/test/TestUtil.java	Thu Mar 31 10:35:28 2005
***************
*** 537,544 ****
                          for (int i = 0; i < expectedFields.length; i++) {
                              j = i + 1;
  
                              //...including null values...
!                             if (results.getString(j) == null) {    //..then we have a null
  
                                  //...check to see if we were expecting it...
                                  if (!expectedFields[i].equalsIgnoreCase(
--- 537,546 ----
                          for (int i = 0; i < expectedFields.length; i++) {
                              j = i + 1;
  
+                             String actual = results.getString(j);
+ 
                              //...including null values...
!                             if (actual == null) {    //..then we have a null
  
                                  //...check to see if we were expecting it...
                                  if (!expectedFields[i].equalsIgnoreCase(
***************
*** 550,557 ****
                                          + "\nbut field " + j
                                          + " contained NULL");
                                  }
!                             } else if (!results.getString(j).equals(
!                                     expectedFields[i])) {
  
                                  //then the results are different
                                  throw new Exception(
--- 552,558 ----
                                          + "\nbut field " + j
                                          + " contained NULL");
                                  }
!                             } else if (!actual.equals(expectedFields[i])) {
  
                                  //then the results are different
                                  throw new Exception(
*** misc/hsqldb/src/org/hsqldb/util/TransferDb.java	Wed Mar  2 14:51:00 2005
--- misc/build/hsqldb/src/org/hsqldb/util/TransferDb.java	Thu Mar 31 10:35:28 2005
***************
*** 215,221 ****
                      tmpTypes = new int[len + 1];
  
                      for (int j = 1; j <= len; j++) {
!                         tmpTypes[i] = r.getColumnType(j);
                      }
                  }
  
--- 215,221 ----
                      tmpTypes = new int[len + 1];
  
                      for (int j = 1; j <= len; j++) {
!                         tmpTypes[j] = r.getColumnType(j);
                      }
                  }
  
