Project

General

Profile

h2_update_perf.patch

Constantin Asofiei, 11/15/2022 06:45 AM

Download (27.8 KB)

View differences:

new/src/main/org/h2/command/dml/Update.java 2022-11-10 10:41:12 +0000
5 5
 */
6 6
package org.h2.command.dml;
7 7

  
8
import java.util.BitSet;
8 9
import java.util.HashSet;
9 10
import java.util.LinkedHashMap;
11
import java.util.List;
12
import java.util.Map;
10 13
import java.util.Map.Entry;
11 14
import java.util.Objects;
12 15

  
......
154 157
                        }
155 158
                    }
156 159
                    Row newRow = table.getTemplateRow();
160
                    newRow.copy(oldRow);
161
                    
162
                    HashSet<Integer> onUpdateColumns = null;
163
                    if (table.getOnUpdateColumns() != null && !table.getOnUpdateColumns().isEmpty())
164
                    {
165
                       onUpdateColumns = new HashSet<>();
166
                       onUpdateColumns.addAll(table.getOnUpdateColumns());
167
                    }
168
                    BitSet changed = new BitSet(columns.length);
169
                    // TODO: all values are from the 'oldRow'
170
                    for (Map.Entry<Column, Expression> entry : setClauseMap.entrySet())
171
                    {
172
                       Column column = entry.getKey();
173
                       Expression newExpr = entry.getValue();
174
                       Value newValue;
175
                       if (newExpr == ValueExpression.getDefault()) 
176
                       {
177
                          newValue = table.getDefaultValue(session, column);
178
                       }
179
                       else 
180
                       {
181
                          newValue = newExpr.getValue(session);
182
                       }
183
                       newRow.setValue(column.getColumnId(), newValue);
184
                       changed.set(column.getColumnId());
185
                       if (onUpdateColumns != null)
186
                       {
187
                          onUpdateColumns.remove(column.getColumnId());
188
                       }
189
                    }
190
                    boolean setOnUpdate = onUpdateColumns != null && !onUpdateColumns.isEmpty();
191
                    /*
157 192
                    boolean setOnUpdate = false;
158 193
                    for (int i = 0; i < columnCount; i++) {
159 194
                        Column column = columns[i];
......
171 206
                        }
172 207
                        newRow.setValue(i, newValue);
173 208
                    }
209
                    */
174 210
                    long key = oldRow.getKey();
175 211
                    newRow.setKey(key);
176
                    table.validateConvertUpdateSequence(session, newRow);
212
                    table.validateConvertUpdateSequence(session, newRow, changed);
177 213
                    if (setOnUpdate || updateToCurrentValuesReturnsZero) {
178 214
                        setOnUpdate = false;
179 215
                        for (int i = 0; i < columnCount; i++) {
......
186 222
                        if (setOnUpdate) {
187 223
                            for (int i = 0; i < columnCount; i++) {
188 224
                                Column column = columns[i];
189
                                if (setClauseMap.get(column) == null) {
225
                                if (!changed.get(column.getColumnId())) {
190 226
                                    if (column.getOnUpdateExpression() != null) {
191 227
                                        newRow.setValue(i, table.getOnUpdateValue(session, column));
192 228
                                    }
......
223 259

  
224 260
            // the cached row is already updated - we need the old values
225 261
            table.updateRows(this, session, rows);
262

  
226 263
            if (table.fireRow()) {
227 264
                for (rows.reset(); rows.hasNext();) {
228 265
                    Row o = rows.next();
new/src/main/org/h2/pagestore/db/TreeIndex.java 2022-11-10 09:45:44 +0000
5 5
 */
6 6
package org.h2.pagestore.db;
7 7

  
8
import java.util.HashMap;
9

  
8 10
import org.h2.command.dml.AllColumnsForPlan;
9 11
import org.h2.engine.Session;
10 12
import org.h2.index.BaseIndex;
......
25 27
public class TreeIndex extends BaseIndex {
26 28

  
27 29
    private TreeNode root;
30
    private HashMap<Long, TreeNode> byKey = new HashMap<>();
28 31
    private final PageStoreTable tableData;
29 32
    private long rowCount;
30 33
    private boolean closed;
......
41 44
    @Override
42 45
    public void close(Session session) {
43 46
        root = null;
47
        byKey.clear();
44 48
        closed = true;
45 49
    }
46 50

  
......
50 54
            throw DbException.throwInternalError();
51 55
        }
52 56
        TreeNode i = new TreeNode(row);
57
        byKey.put(row.getKey(), i);
53 58
        TreeNode n = root, x = n;
54 59
        boolean isLeft = true;
55 60
        while (true) {
......
157 162
        if (x == null) {
158 163
            throw DbException.throwInternalError("not found!");
159 164
        }
165
        byKey.remove(row.getKey());
166
        
160 167
        TreeNode n;
161 168
        if (x.left == null) {
162 169
            n = x.right;
......
272 279
    }
273 280

  
274 281
    private TreeNode findFirstNode(SearchRow row, boolean withKey) {
282
       TreeNode k = null; 
283
       if (withKey)
284
       {
285
          k = byKey.get(row.getKey());
286
          return k;
287
       }
288
       
275 289
        TreeNode x = root, result = x;
276 290
        while (x != null) {
277 291
            result = x;
......
334 348
    @Override
335 349
    public void truncate(Session session) {
336 350
        root = null;
351
        byKey.clear();
337 352
        rowCount = 0;
338 353
    }
339 354

  
new/src/main/org/h2/res/javadoc.properties 2022-11-10 10:24:44 +0000
1
org.h2.tools.Backup=Creates a backup of a database.\nThis tool copies all database files. The database must be closed before using\n this tool. To create a backup while the database is in use, run the BACKUP\n SQL statement. In an emergency, for example if the application is not\n responding, creating a backup using the Backup tool is possible by using the\n quiet mode. However, if the database is changed while the backup is running\n in quiet mode, the backup could be corrupt.
2
org.h2.jmx.DatabaseInfoMBean.listSettings=List the database settings.
3
org.h2.tools.Server=Starts the H2 Console (web-) server, TCP, and PG server.
4
org.h2.jmx.DatabaseInfoMBean.listSessions=List sessions, including the queries that are in\n progress, and locked tables.
5
org.h2.jmx.DatabaseInfoMBean.isExclusive=Is the database open in exclusive mode?
1
org.h2.jmx.DatabaseInfoMBean=Information and management operations for the given database.
6 2
org.h2.jmx.DatabaseInfoMBean.getCacheSize=The current cache size in KB.
7
org.h2.tools.DeleteDbFiles.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]   Print the list of options\n[-dir <dir>]      The directory (default\: .)\n[-db <database>]  The database name\n[-quiet]          Do not print progress information
8 3
org.h2.jmx.DatabaseInfoMBean.getCacheSizeMax=The maximum cache size in KB.
9
org.h2.tools.CreateCluster.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]       Print the list of options\n[-urlSource "<url>"]  The database URL of the source database (jdbc\:h2\:...)\n[-urlTarget "<url>"]  The database URL of the target database (jdbc\:h2\:...)\n[-user <user>]        The user name (default\: sa)\n[-password <pwd>]     The password\n[-serverList <list>]  The comma separated list of host names or IP addresses
4
org.h2.jmx.DatabaseInfoMBean.getFileReadCount=The file read count since the database was opened.
5
org.h2.jmx.DatabaseInfoMBean.getFileSize=The database file size in KB.
6
org.h2.jmx.DatabaseInfoMBean.getFileWriteCount=The number of write operations since the database was opened.
7
org.h2.jmx.DatabaseInfoMBean.getFileWriteCountTotal=The number of write operations since the database was created.
8
org.h2.jmx.DatabaseInfoMBean.getLogMode=The transaction log mode (0 disabled, 1 without sync, 2 enabled).
9
org.h2.jmx.DatabaseInfoMBean.getMode=The database compatibility mode (REGULAR if no compatibility mode is\n used).
10 10
org.h2.jmx.DatabaseInfoMBean.getTraceLevel=The trace level (0 disabled, 1 error, 2 info, 3 debug).
11
org.h2.tools.Server.main=When running without options, -tcp, -web, -browser and -pg are started.\nOptions are case sensitive. Supported options are\:\n[-help] or [-?]         Print the list of options\n[-web]                  Start the web server with the H2 Console\n[-webAllowOthers]       Allow other computers to connect - see below\n[-webDaemon]            Use a daemon thread\n[-webPort <port>]       The port (default\: 8082)\n[-webSSL]               Use encrypted (HTTPS) connections\n[-webAdminPassword]     Password of DB Console administrator\n[-browser]              Start a browser connecting to the web server\n[-tcp]                  Start the TCP server\n[-tcpAllowOthers]       Allow other computers to connect - see below\n[-tcpDaemon]            Use a daemon thread\n[-tcpPort <port>]       The port (default\: 9092)\n[-tcpSSL]               Use encrypted (SSL) connections\n[-tcpPassword <pwd>]    The password for shutting down a TCP server\n[-tcpShutdown "<url>"]  Stop the TCP server; example\: tcp\://localhost\n[-tcpShutdownForce]     Do not wait until all connections are closed\n[-pg]                   Start the PG server\n[-pgAllowOthers]        Allow other computers to connect - see below\n[-pgDaemon]             Use a daemon thread\n[-pgPort <port>]        The port (default\: 5435)\n[-properties "<dir>"]   Server properties (default\: ~, disable\: null)\n[-baseDir <dir>]        The base directory for H2 databases (all servers)\n[-ifExists]             Only existing databases may be opened (all servers)\n[-ifNotExists]          Databases are created when accessed\n[-trace]                Print additional trace information (all servers)\n[-key <from> <to>]      Allows to map a database name to another (all servers)\nThe options -xAllowOthers are potentially risky.\nFor details, see Advanced Topics / Protection against Remote Access.
11
org.h2.jmx.DatabaseInfoMBean.getVersion=The database version.
12
org.h2.jmx.DatabaseInfoMBean.isExclusive=Is the database open in exclusive mode?
13
org.h2.jmx.DatabaseInfoMBean.isMultiThreaded=Is multi-threading enabled?
12 14
org.h2.jmx.DatabaseInfoMBean.isMvcc=Is MVCC (multi version concurrency) enabled?
13
org.h2.tools.Shell=Interactive command line tool to access a database using JDBC.
15
org.h2.jmx.DatabaseInfoMBean.isReadOnly=Is the database read-only?
16
org.h2.jmx.DatabaseInfoMBean.listSessions=List sessions, including the queries that are in\n progress, and locked tables.
17
org.h2.jmx.DatabaseInfoMBean.listSettings=List the database settings.
18
org.h2.tools.Backup=Creates a backup of a database.\nThis tool copies all database files. The database must be closed before using\n this tool. To create a backup while the database is in use, run the BACKUP\n SQL statement. In an emergency, for example if the application is not\n responding, creating a backup using the Backup tool is possible by using the\n quiet mode. However, if the database is changed while the backup is running\n in quiet mode, the backup could be corrupt.
19
org.h2.tools.Backup.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]     Print the list of options\n[-file <filename>]  The target file name (default\: backup.zip)\n[-dir <dir>]        The source directory (default\: .)\n[-db <database>]    Source database; not required if there is only one\n[-quiet]            Do not print progress information
20
org.h2.tools.ChangeFileEncryption=Allows changing the database file encryption password or algorithm.\nThis tool can not be used to change a password of a user.\n The database must be closed before using this tool.
21
org.h2.tools.ChangeFileEncryption.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]   Print the list of options\n[-cipher type]    The encryption type (AES)\n[-dir <dir>]      The database directory (default\: .)\n[-db <database>]  Database name (all databases if not set)\n[-decrypt <pwd>]  The decryption password (if not set\: not yet encrypted)\n[-encrypt <pwd>]  The encryption password (if not set\: do not encrypt)\n[-quiet]          Do not print progress information
22
org.h2.tools.Console=Starts the H2 Console (web-) server, as well as the TCP and PG server.
23
org.h2.tools.Console.main=When running without options, -tcp, -web, -browser and -pg are started.\nOptions are case sensitive. Supported options are\:\n[-help] or [-?]  Print the list of options\n[-url]           Start a browser and connect to this URL\n[-driver]        Used together with -url\: the driver\n[-user]          Used together with -url\: the user name\n[-password]      Used together with -url\: the password\n[-web]           Start the web server with the H2 Console\n[-tool]          Start the icon or window that allows to start a browser\n[-browser]       Start a browser connecting to the web server\n[-tcp]           Start the TCP server\n[-pg]            Start the PG server\nFor each Server, additional options are available;\n for details, see the Server tool.\nIf a service can not be started, the program\n terminates with an exit code of 1.
14 24
org.h2.tools.ConvertTraceFile=Converts a .trace.db file to a SQL script and Java source code.\nSQL statement statistics are listed as well.
15
org.h2.jmx.DatabaseInfoMBean.getFileReadCount=The file read count since the database was opened.
16
org.h2.jmx.DatabaseInfoMBean.getMode=The database compatibility mode (REGULAR if no compatibility mode is\n used).
17
org.h2.tools.Console.main=When running without options, -tcp, -web, -browser and -pg are started.\nOptions are case sensitive. Supported options are\:\n[-help] or [-?]  Print the list of options\n[-url]           Start a browser and connect to this URL\n[-driver]        Used together with -url\: the driver\n[-user]          Used together with -url\: the user name\n[-password]      Used together with -url\: the password\n[-web]           Start the web server with the H2 Console\n[-tool]          Start the icon or window that allows to start a browser\n[-browser]       Start a browser connecting to the web server\n[-tcp]           Start the TCP server\n[-pg]            Start the PG server\nFor each Server, additional options are available;\n for details, see the Server tool.\nIf a service can not be started, the program\n terminates with an exit code of 1.
18
org.h2.jmx.DatabaseInfoMBean.getLogMode=The transaction log mode (0 disabled, 1 without sync, 2 enabled).
19
org.h2.tools.Restore.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]     Print the list of options\n[-file <filename>]  The source file name (default\: backup.zip)\n[-dir <dir>]        The target directory (default\: .)\n[-db <database>]    The target database name (as stored if not set)\n[-quiet]            Do not print progress information
20
org.h2.tools.Restore=Restores a H2 database by extracting the database files from a .zip file.
21
org.h2.tools.RunScript.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]     Print the list of options\n[-url "<url>"]      The database URL (jdbc\:...)\n[-user <user>]      The user name (default\: sa)\n[-password <pwd>]   The password\n[-script <file>]    The script file to run (default\: backup.sql)\n[-driver <class>]   The JDBC driver class to use (not required in most cases)\n[-showResults]      Show the statements and the results of queries\n[-checkResults]     Check if the query results match the expected results\n[-continueOnError]  Continue even if the script contains errors\n[-options ...]      RUNSCRIPT options (embedded H2; -*Results not supported)
22
org.h2.jmx.DatabaseInfoMBean.getFileWriteCountTotal=The number of write operations since the database was created.
23 25
org.h2.tools.ConvertTraceFile.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]      Print the list of options\n[-traceFile <file>]  The trace file name (default\: test.trace.db)\n[-script <file>]     The script file name (default\: test.sql)\n[-javaClass <file>]  The Java directory and class file name (default\: Test)
26
org.h2.tools.CreateCluster=Creates a cluster from a stand-alone database.\nCopies a database to another location if required.
27
org.h2.tools.CreateCluster.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]       Print the list of options\n[-urlSource "<url>"]  The database URL of the source database (jdbc\:h2\:...)\n[-urlTarget "<url>"]  The database URL of the target database (jdbc\:h2\:...)\n[-user <user>]        The user name (default\: sa)\n[-password <pwd>]     The password\n[-serverList <list>]  The comma separated list of host names or IP addresses
24 28
org.h2.tools.DeleteDbFiles=Deletes all files belonging to a database.\nThe database must be closed before calling this tool.
25
org.h2.tools.ChangeFileEncryption.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]   Print the list of options\n[-cipher type]    The encryption type (AES)\n[-dir <dir>]      The database directory (default\: .)\n[-db <database>]  Database name (all databases if not set)\n[-decrypt <pwd>]  The decryption password (if not set\: not yet encrypted)\n[-encrypt <pwd>]  The encryption password (if not set\: do not encrypt)\n[-quiet]          Do not print progress information
26
org.h2.tools.Console=Starts the H2 Console (web-) server, as well as the TCP and PG server.
27
org.h2.jmx.DatabaseInfoMBean.isReadOnly=Is the database read-only?
29
org.h2.tools.DeleteDbFiles.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]   Print the list of options\n[-dir <dir>]      The directory (default\: .)\n[-db <database>]  The database name\n[-quiet]          Do not print progress information
30
org.h2.tools.Recover=Helps recovering a corrupted database.
28 31
org.h2.tools.Recover.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]    Print the list of options\n[-dir <dir>]       The directory (default\: .)\n[-db <database>]   The database name (all databases if not set)\n[-trace]           Print additional trace information\n[-transactionLog]  Print the transaction log\nEncrypted databases need to be decrypted first.
32
org.h2.tools.Restore=Restores a H2 database by extracting the database files from a .zip file.
33
org.h2.tools.Restore.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]     Print the list of options\n[-file <filename>]  The source file name (default\: backup.zip)\n[-dir <dir>]        The target directory (default\: .)\n[-db <database>]    The target database name (as stored if not set)\n[-quiet]            Do not print progress information
29 34
org.h2.tools.RunScript=Runs a SQL script against a database.
35
org.h2.tools.RunScript.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]     Print the list of options\n[-url "<url>"]      The database URL (jdbc\:...)\n[-user <user>]      The user name (default\: sa)\n[-password <pwd>]   The password\n[-script <file>]    The script file to run (default\: backup.sql)\n[-driver <class>]   The JDBC driver class to use (not required in most cases)\n[-showResults]      Show the statements and the results of queries\n[-checkResults]     Check if the query results match the expected results\n[-continueOnError]  Continue even if the script contains errors\n[-options ...]      RUNSCRIPT options (embedded H2; -*Results not supported)
36
org.h2.tools.Script=Creates a SQL script file by extracting the schema and data of a database.
30 37
org.h2.tools.Script.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]    Print the list of options\n[-url "<url>"]     The database URL (jdbc\:...)\n[-user <user>]     The user name (default\: sa)\n[-password <pwd>]  The password\n[-script <file>]   The target script file name (default\: backup.sql)\n[-options ...]     A list of options (only for embedded H2, see SCRIPT)\n[-quiet]           Do not print progress information
31
org.h2.jmx.DatabaseInfoMBean.getFileWriteCount=The number of write operations since the database was opened.
32
org.h2.tools.Script=Creates a SQL script file by extracting the schema and data of a database.
33
org.h2.tools.Recover=Helps recovering a corrupted database.
34
org.h2.tools.ChangeFileEncryption=Allows changing the database file encryption password or algorithm.\nThis tool can not be used to change a password of a user.\n The database must be closed before using this tool.
35
org.h2.jmx.DatabaseInfoMBean.isMultiThreaded=Is multi-threading enabled?
36
org.h2.jmx.DatabaseInfoMBean.getVersion=The database version.
38
org.h2.tools.Server=Starts the H2 Console (web-) server, TCP, and PG server.
39
org.h2.tools.Server.main=When running without options, -tcp, -web, -browser and -pg are started.\nOptions are case sensitive. Supported options are\:\n[-help] or [-?]         Print the list of options\n[-web]                  Start the web server with the H2 Console\n[-webAllowOthers]       Allow other computers to connect - see below\n[-webDaemon]            Use a daemon thread\n[-webPort <port>]       The port (default\: 8082)\n[-webSSL]               Use encrypted (HTTPS) connections\n[-webAdminPassword]     Password of DB Console administrator\n[-browser]              Start a browser connecting to the web server\n[-tcp]                  Start the TCP server\n[-tcpAllowOthers]       Allow other computers to connect - see below\n[-tcpDaemon]            Use a daemon thread\n[-tcpPort <port>]       The port (default\: 9092)\n[-tcpSSL]               Use encrypted (SSL) connections\n[-tcpPassword <pwd>]    The password for shutting down a TCP server\n[-tcpShutdown "<url>"]  Stop the TCP server; example\: tcp\://localhost\n[-tcpShutdownForce]     Do not wait until all connections are closed\n[-pg]                   Start the PG server\n[-pgAllowOthers]        Allow other computers to connect - see below\n[-pgDaemon]             Use a daemon thread\n[-pgPort <port>]        The port (default\: 5435)\n[-properties "<dir>"]   Server properties (default\: ~, disable\: null)\n[-baseDir <dir>]        The base directory for H2 databases (all servers)\n[-ifExists]             Only existing databases may be opened (all servers)\n[-ifNotExists]          Databases are created when accessed\n[-trace]                Print additional trace information (all servers)\n[-key <from> <to>]      Allows to map a database name to another (all servers)\nThe options -xAllowOthers are potentially risky.\nFor details, see Advanced Topics / Protection against Remote Access.
40
org.h2.tools.Shell=Interactive command line tool to access a database using JDBC.
37 41
org.h2.tools.Shell.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]        Print the list of options\n[-url "<url>"]         The database URL (jdbc\:h2\:...)\n[-user <user>]         The user name\n[-password <pwd>]      The password\n[-driver <class>]      The JDBC driver class to use (not required in most cases)\n[-sql "<statements>"]  Execute the SQL statements and exit\n[-properties "<dir>"]  Load the server properties from this directory\nIf special characters don't work as expected, you may need to use\n -Dfile.encoding\=UTF-8 (Mac OS X) or CP850 (Windows).
38
org.h2.tools.CreateCluster=Creates a cluster from a stand-alone database.\nCopies a database to another location if required.
39
org.h2.jmx.DatabaseInfoMBean=Information and management operations for the given database.
40
org.h2.tools.Backup.main=Options are case sensitive. Supported options are\:\n[-help] or [-?]     Print the list of options\n[-file <filename>]  The target file name (default\: backup.zip)\n[-dir <dir>]        The source directory (default\: .)\n[-db <database>]    Source database; not required if there is only one\n[-quiet]            Do not print progress information
41
org.h2.jmx.DatabaseInfoMBean.getFileSize=The database file size in KB.
new/src/main/org/h2/result/Row.java 2022-11-10 09:01:07 +0000
66 66
     */
67 67
    boolean hasSharedData(Row other);
68 68

  
69
   void copy(Row oldRow);
70

  
69 71
}
new/src/main/org/h2/result/RowImpl.java 2022-11-10 09:04:22 +0000
25 25
    }
26 26

  
27 27
    @Override
28
   public void copy(Row src)
29
   {
30
       System.arraycopy(((RowImpl) src).data, 0, data, 0, data.length);
31
   }
32
    
33
    @Override
28 34
    public void setKey(SearchRow row) {
29 35
        setKey(row.getKey());
30 36
    }
new/src/main/org/h2/table/Table.java 2022-11-10 09:03:25 +0000
62 62
    /**
63 63
     * The indexes of the computed columns
64 64
     */
65
    protected List<Integer> computedColumns = new ArrayList<>();
65
    protected List<Integer> computedColumns = null;
66
    
67
    private List<Integer> onUpdateColumns = null;
66 68

  
67 69
    /**
68 70
     * The compare mode used for this table.
......
271 273
     */
272 274
    public abstract ArrayList<Index> getIndexes();
273 275

  
276
    public List<Integer> getOnUpdateColumns()
277
   {
278
      return onUpdateColumns;
279
   }
280
    
274 281
    /**
275 282
     * Get an index by name.
276 283
     *
......
435 442
        if (columnMap.size() > 0) {
436 443
            columnMap.clear();
437 444
        }
438
        if (computedColumns.size() > 0) {
445
        if (computedColumns != null && computedColumns.size() > 0) {
439 446
           computedColumns.clear();
440 447
        }
448
        if (onUpdateColumns != null && onUpdateColumns.size() > 0)
449
        {
450
           onUpdateColumns.clear();
451
        }
441 452
        
442 453
        for (int i = 0; i < columns.length; i++) {
443 454
            Column col = columns[i];
......
453 464
            }
454 465
            columnMap.put(columnName, col);
455 466
            if (col.getComputed()) {
467
               if (computedColumns == null)
468
               {
469
                  computedColumns = new ArrayList<>();
470
               }
456 471
               computedColumns.add(i);
457 472
            }
473
            if (col.getOnUpdateExpression() != null)
474
            {
475
               if (onUpdateColumns == null)
476
               {
477
                  onUpdateColumns = new ArrayList<>();
478
               }
479
               onUpdateColumns.add(i);
480
            }
458 481
        }
459 482
    }
460 483

  
......
841 864
     * @param row the row
842 865
     */
843 866
    public void validateConvertUpdateSequence(Session session, Row row) {
844
        for (int i = 0; i < computedColumns.size(); i++)
845
        {
846
            int idx = computedColumns.get(i);
847
            row.setValue(idx, columns[idx].computeValue(session, row));
848
        }
849
        
867
       validateConvertUpdateSequence(session, row, null);
868
    }
869
    
870
    /**
871
     * Validate all values in this row, convert the values if required, and
872
     * update the sequence values if required. This call will also set the
873
     * default values if required and set the computed column if there are any.
874
     *
875
     * @param session the session
876
     * @param row the row
877
     */
878
    public void validateConvertUpdateSequence(Session session, Row row, BitSet setCols) {
879
       BitSet changed = null;
880
       if (setCols != null)
881
       {
882
          changed = new BitSet();
883
          changed.or(setCols);
884
       }
885
       
886
       if (computedColumns != null)
887
       {
888
           for (int i = 0; i < computedColumns.size(); i++)
889
           {
890
               int idx = computedColumns.get(i);
891
               row.setValue(idx, columns[idx].computeValue(session, row));
892
               if (changed != null)
893
               {
894
                  changed.set(idx);
895
               }
896
           }
897
       }
898
       
850 899
        for (int i = 0; i < columns.length; i++) {
900
           if (changed != null && !changed.get(i))
901
           {
902
              // only changed columns
903
              continue;
904
           }
905
           
851 906
           Value value = row.getValue(i);
852 907
           Value v2 = columns[i].validateConvertUpdateSequence(session, value);
853 908
           if (v2 != value) {