ttomcat-1778514358873.zip-extract/_dependencies/maven/com.h2database_h2-2.2.220/org/h2/result/LocalResult.java

Path
ttomcat-1778514358873.zip-extract/_dependencies/maven/com.h2database_h2-2.2.220/org/h2/result/LocalResult.java
Status
scanned
Type
file
Name
LocalResult.java
Extension
.java
Programming language
Java
Mime type
text/x-java
File type
Java source, ASCII text
Tag

      
    
Rootfs path

      
    
Size
20548 (20.1 KB)
MD5
bd7da982b6ce323fa269f788aa64c72e
SHA1
d5bc79bb48f688f4f3c775dffa0595bad009a474
SHA256
66e8d2213b591d1b4d60ddcf55407ffcd11669f7ac4f3751952a8ba41e9e2a7e
SHA512

      
    
SHA1_git
01478a62e300efe71e76684f10fe2a03af02bc3c
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
LocalResult.java | 20.1 KB |

/* * Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0, * and the EPL 1.0 (https://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.result; import java.util.ArrayList; import java.util.Arrays; import java.util.TreeMap; import org.h2.engine.Database; import org.h2.engine.Session; import org.h2.engine.SessionLocal; import org.h2.engine.SysProperties; import org.h2.expression.Expression; import org.h2.expression.ExpressionColumn; import org.h2.message.DbException; import org.h2.mvstore.db.MVTempResult; import org.h2.table.Column; import org.h2.table.Table; import org.h2.util.Utils; import org.h2.value.TypeInfo; import org.h2.value.Value; import org.h2.value.ValueBigint; import org.h2.value.ValueLob; import org.h2.value.ValueRow; /** * A local result set contains all row data of a result set. * This is the object generated by engine, * and it is also used directly by the ResultSet class in the embedded mode. * If the result does not fit in memory, it is written to a temporary file. */ public class LocalResult implements ResultInterface, ResultTarget { /** * Constructs a new local result object for the specified table. * * @param session * the session * @param table * the table * @return the local result */ public static LocalResult forTable(SessionLocal session, Table table) { Column[] columns = table.getColumns(); int degree = columns.length; Expression[] expressions = new Expression[degree + 1]; Database database = session.getDatabase(); for (int i = 0; i < degree; i++) { expressions[i] = new ExpressionColumn(database, columns[i]); } Column rowIdColumn = table.getRowIdColumn(); expressions[degree] = rowIdColumn != null ? new ExpressionColumn(database, rowIdColumn) : new ExpressionColumn(database, null, table.getName()); return new LocalResult(session, expressions, degree, degree + 1); } private int maxMemoryRows; private final SessionLocal session; private int visibleColumnCount; private int resultColumnCount; private Expression[] expressions; private boolean forDataChangeDeltaTable; private long rowId, rowCount; private ArrayList<Value[]> rows; private SortOrder sort; // HashSet cannot be used here, because we need to compare values of // different type or scale properly. private TreeMap<ValueRow, Value[]> distinctRows; private Value[] currentRow; private long offset; private long limit = -1; private boolean fetchPercent; private SortOrder withTiesSortOrder; private boolean limitsWereApplied; private ResultExternal external; private boolean distinct; private int[] distinctIndexes; private boolean closed; private boolean containsLobs; private Boolean containsNull; /** * Construct a local result object. */ public LocalResult() { this(null); } private LocalResult(SessionLocal session) { this.session = session; } /** * Construct a local result object. * * @param session * the session * @param expressions * the expression array * @param visibleColumnCount * the number of visible columns * @param resultColumnCount * the number of columns including visible columns and additional * virtual columns for ORDER BY and DISTINCT ON clauses */ public LocalResult(SessionLocal session, Expression[] expressions, int visibleColumnCount, int resultColumnCount) { this.session = session; if (session == null) { this.maxMemoryRows = Integer.MAX_VALUE; } else { Database db = session.getDatabase(); if (db.isPersistent() && !db.isReadOnly()) { this.maxMemoryRows = session.getDatabase().getMaxMemoryRows(); } else { this.maxMemoryRows = Integer.MAX_VALUE; } } rows = Utils.newSmallArrayList(); this.visibleColumnCount = visibleColumnCount; this.resultColumnCount = resultColumnCount; rowId = -1; this.expressions = expressions; } @Override public boolean isLazy() { return false; } /** * Redefine count of maximum rows holds in memory for the result. * * @param maxValue Maximum rows count in memory. * * @see SysProperties#MAX_MEMORY_ROWS */ public void setMaxMemoryRows(int maxValue) { this.maxMemoryRows = maxValue; } /** * Sets value collection mode for data change delta tables. */ public void setForDataChangeDeltaTable() { forDataChangeDeltaTable = true; } /** * Create a shallow copy of the result set. The data and a temporary table * (if there is any) is not copied. * * @param targetSession the session of the copy * @return the copy if possible, or null if copying is not possible */ @Override public LocalResult createShallowCopy(Session targetSession) { if (external == null && (rows == null || rows.size() < rowCount)) { return null; } if (containsLobs) { return null; } ResultExternal e2 = null; if (external != null) { e2 = external.createShallowCopy(); if (e2 == null) { return null; } } LocalResult copy = new LocalResult((SessionLocal) targetSession); copy.maxMemoryRows = this.maxMemoryRows; copy.visibleColumnCount = this.visibleColumnCount; copy.resultColumnCount = this.resultColumnCount; copy.expressions = this.expressions; copy.rowId = -1; copy.rowCount = this.rowCount; copy.rows = this.rows; copy.sort = this.sort; copy.distinctRows = this.distinctRows; copy.distinct = distinct; copy.distinctIndexes = distinctIndexes; copy.currentRow = null; copy.offset = 0; copy.limit = -1; copy.external = e2; copy.containsNull = containsNull; return copy; } /** * Sets sort order to be used by this result. When rows are presorted by the * query this method should not be used. * * @param sort the sort order */ public void setSortOrder(SortOrder sort) { this.sort = sort; } /** * Remove duplicate rows. */ public void setDistinct() { assert distinctIndexes == null; distinct = true; distinctRows = new TreeMap<>(session.getDatabase().getCompareMode()); } /** * Remove rows with duplicates in columns with specified indexes. * * @param distinctIndexes distinct indexes */ public void setDistinct(int[] distinctIndexes) { assert !distinct; this.distinctIndexes = distinctIndexes; distinctRows = new TreeMap<>(session.getDatabase().getCompareMode()); } /** * @return whether this result is a distinct result */ private boolean isAnyDistinct() { return distinct || distinctIndexes != null; } /** * Check if this result set contains the given row. * * @param values the row * @return true if the row exists */ public boolean containsDistinct(Value[] values) { assert values.length == visibleColumnCount; if (external != null) { return external.contains(values); } if (distinctRows == null) { distinctRows = new TreeMap<>(session.getDatabase().getCompareMode()); for (Value[] row : rows) { ValueRow array = getDistinctRow(row); distinctRows.put(array, array.getList()); } } ValueRow array = ValueRow.get(values); return distinctRows.get(array) != null; } /** * Check if this result set contains a NULL value. This method may reset * this result. * * @return true if there is a NULL value */ public boolean containsNull() { Boolean r = containsNull; if (r == null) { r = false; reset(); loop: while (next()) { Value[] row = currentRow; for (int i = 0; i < visibleColumnCount; i++) { if (row[i].containsNull()) { r = true; break loop; } } } reset(); containsNull = r; } return r; } /** * Remove the row from the result set if it exists. * * @param values the row */ public void removeDistinct(Value[] values) { if (!distinct) { throw DbException.getInternalError(); } assert values.length == visibleColumnCount; if (distinctRows != null) { distinctRows.remove(ValueRow.get(values)); rowCount = distinctRows.size(); } else { rowCount = external.removeRow(values); } } @Override public void reset() { rowId = -1; currentRow = null; if (external != null) { external.reset(); } } /** * Retrieve the current row * @return row */ public Row currentRowForTable() { int degree = visibleColumnCount; Value[] currentRow = this.currentRow; Row row = session.getDatabase().getRowFactory() .createRow(Arrays.copyOf(currentRow, degree), SearchRow.MEMORY_CALCULATE); row.setKey(currentRow[degree].getLong()); return row; } @Override public Value[] currentRow() { return currentRow; } @Override public boolean next() { if (!closed && rowId < rowCount) { rowId++; if (rowId < rowCount) { if (external != null) { currentRow = external.next(); } else { currentRow = rows.get((int) rowId); } return true; } currentRow = null; } return false; } @Override public long getRowId() { return rowId; } @Override public boolean isAfterLast() { return rowId >= rowCount; } private void cloneLobs(Value[] values) { for (int i = 0; i < values.length; i++) { Value v = values[i]; if (v instanceof ValueLob) { if (forDataChangeDeltaTable) { containsLobs = true; } else { ValueLob v2 = ((ValueLob) v).copyToResult(); if (v2 != v) { containsLobs = true; values[i] = session.addTemporaryLob(v2); } } } } } private ValueRow getDistinctRow(Value[] values) { if (distinctIndexes != null) { int cnt = distinctIndexes.length; Value[] newValues = new Value[cnt]; for (int i = 0; i < cnt; i++) { newValues[i] = values[distinctIndexes[i]]; } values = newValues; } else if (values.length > visibleColumnCount) { values = Arrays.copyOf(values, visibleColumnCount); } return ValueRow.get(values); } private void createExternalResult() { external = MVTempResult.of(session.getDatabase(), expressions, distinct, distinctIndexes, visibleColumnCount, resultColumnCount, sort); } /** * Add a row for a table. * * @param row the row to add */ public void addRowForTable(Row row) { int degree = visibleColumnCount; Value[] values = new Value[degree + 1]; for (int i = 0; i < degree; i++) { values[i] = row.getValue(i); } values[degree] = ValueBigint.get(row.getKey()); addRowInternal(values); } /** * Add a row to this object. * * @param values the row to add */ @Override public void addRow(Value... values) { assert values.length == resultColumnCount; cloneLobs(values); addRowInternal(values); } private void addRowInternal(Value... values) { if (isAnyDistinct()) { if (distinctRows != null) { ValueRow distinctRow = getDistinctRow(values); Value[] previous = distinctRows.get(distinctRow); if (previous == null || sort != null && sort.compare(previous, values) > 0) { distinctRows.put(distinctRow, values); } rowCount = distinctRows.size(); if (rowCount > maxMemoryRows) { createExternalResult(); rowCount = external.addRows(distinctRows.values()); distinctRows = null; } } else { rowCount = external.addRow(values); } } else { rows.add(values); rowCount++; if (rows.size() > maxMemoryRows) { addRowsToDisk(); } } } private void addRowsToDisk() { if (external == null) { createExternalResult(); } rowCount = external.addRows(rows); rows.clear(); } @Override public int getVisibleColumnCount() { return visibleColumnCount; } /** * This method is called after all rows have been added. */ public void done() { if (external != null) { addRowsToDisk(); } else { if (isAnyDistinct()) { rows = new ArrayList<>(distinctRows.values()); } if (sort != null && limit != 0 && !limitsWereApplied) { boolean withLimit = limit > 0 && withTiesSortOrder == null; if (offset > 0 || withLimit) { int endExclusive = rows.size(); if (offset < endExclusive) { int fromInclusive = (int) offset; if (withLimit && limit < endExclusive - fromInclusive) { endExclusive = fromInclusive + (int) limit; } sort.sort(rows, fromInclusive, endExclusive); } } else { sort.sort(rows); } } } applyOffsetAndLimit(); reset(); } private void applyOffsetAndLimit() { if (limitsWereApplied) { return; } long offset = Math.max(this.offset, 0); long limit = this.limit; if (offset == 0 && limit < 0 && !fetchPercent || rowCount == 0) { return; } if (fetchPercent) { if (limit < 0 || limit > 100) { throw DbException.getInvalidValueException("FETCH PERCENT", limit); } // Oracle rounds percent up, do the same for now limit = (limit * rowCount + 99) / 100; } boolean clearAll = offset >= rowCount || limit == 0; if (!clearAll) { long remaining = rowCount - offset; limit = limit < 0 ? remaining : Math.min(remaining, limit); if (offset == 0 && remaining <= limit) { return; } } else { limit = 0; } distinctRows = null; rowCount = limit; if (external == null) { if (clearAll) { rows.clear(); return; } int to = (int) (offset + limit); if (withTiesSortOrder != null) { Value[] expected = rows.get(to - 1); while (to < rows.size() && withTiesSortOrder.compare(expected, rows.get(to)) == 0) { to++; rowCount++; } } if (offset != 0 || to != rows.size()) { // avoid copying the whole array for each row rows = new ArrayList<>(rows.subList((int) offset, to)); } } else { if (clearAll) { external.close(); external = null; return; } trimExternal(offset, limit); } } private void trimExternal(long offset, long limit) { ResultExternal temp = external; external = null; temp.reset(); while (--offset >= 0) { temp.next(); } Value[] row = null; while (--limit >= 0) { row = temp.next(); rows.add(row); if (rows.size() > maxMemoryRows) { addRowsToDisk(); } } if (withTiesSortOrder != null && row != null) { Value[] expected = row; while ((row = temp.next()) != null && withTiesSortOrder.compare(expected, row) == 0) { rows.add(row); rowCount++; if (rows.size() > maxMemoryRows) { addRowsToDisk(); } } } if (external != null) { addRowsToDisk(); } temp.close(); } @Override public long getRowCount() { return rowCount; } @Override public void limitsWereApplied() { this.limitsWereApplied = true; } @Override public boolean hasNext() { return !closed && rowId < rowCount - 1; } /** * Set the number of rows that this result will return at the maximum. * * @param limit the limit (-1 means no limit, 0 means no rows) */ public void setLimit(long limit) { this.limit = limit; } /** * @param fetchPercent whether limit expression specifies percentage of rows */ public void setFetchPercent(boolean fetchPercent) { this.fetchPercent = fetchPercent; } /** * Enables inclusion of tied rows to result and sets the sort order for tied * rows. The specified sort order must be the same as sort order if sort * order was set. Passed value will be used if sort order was not set that * is possible when rows are presorted. * * @param withTiesSortOrder the sort order for tied rows */ public void setWithTies(SortOrder withTiesSortOrder) { assert sort == null || sort == withTiesSortOrder; this.withTiesSortOrder = withTiesSortOrder; } @Override public boolean needToClose() { return external != null; } @Override public void close() { if (external != null) { external.close(); external = null; closed = true; } } @Override public String getAlias(int i) { return expressions[i].getAlias(session, i); } @Override public String getTableName(int i) { return expressions[i].getTableName(); } @Override public String getSchemaName(int i) { return expressions[i].getSchemaName(); } @Override public String getColumnName(int i) { return expressions[i].getColumnName(session, i); } @Override public TypeInfo getColumnType(int i) { return expressions[i].getType(); } @Override public int getNullable(int i) { return expressions[i].getNullable(); } @Override public boolean isIdentity(int i) { return expressions[i].isIdentity(); } /** * Set the offset of the first row to return. * * @param offset the offset */ public void setOffset(long offset) { this.offset = offset; } @Override public String toString() { return super.toString() + " columns: " + visibleColumnCount + " rows: " + rowCount + " pos: " + rowId; } /** * Check if this result set is closed. * * @return true if it is */ @Override public boolean isClosed() { return closed; } @Override public int getFetchSize() { return 0; } @Override public void setFetchSize(int fetchSize) { // ignore } }
Detected license expression

      
    
Detected license expression (SPDX)

      
    
Percentage of license text
0.6
Copyrights
- end_line: 2
  copyright: Copyright 2004-2023 H2 Group. Multiple-Licensed
  start_line: 2
Holders
- holder: H2 Group. Multiple-Licensed
  end_line: 2
  start_line: 2
Authors

      
    
License expression License clue details
(mpl-2.0 OR epl-1.0) AND proprietary-license {'score': 20.37, 'matcher': '3-seq', 'end_line': 3, 'rule_url': 'https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mpl-2.0_or_epl-1.0_and_proprietary-license_2.RULE', 'from_file': None, 'start_line': 2, 'matched_text': ' * Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0,\n * and the EPL 1.0 (https://h2database.com/html/license.html).', 'match_coverage': 20.37, 'matched_length': 11, 'rule_relevance': 100, 'rule_identifier': 'mpl-2.0_or_epl-1.0_and_proprietary-license_2.RULE', 'license_expression': '(mpl-2.0 OR epl-1.0) AND proprietary-license', 'license_expression_spdx': '(MPL-2.0 OR EPL-1.0) AND LicenseRef-scancode-proprietary-license'}
URL Start line End line
https://h2database.com/html/license.html 3 3
Package URL License Primary language
pkg:osgi/com.h2database.source@2.2.220