Unverified 提交 24108bee authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1601 from katzyn/rownum

Return BIGINT from ROWNUM(), ROW_NUMBER() and rank functions
...@@ -5139,7 +5139,7 @@ READONLY() ...@@ -5139,7 +5139,7 @@ READONLY()
ROWNUM() ROWNUM()
"," ","
Returns the number of the current row. Returns the number of the current row.
This method returns an integer value. This method returns a long value.
It is supported for SELECT statements, as well as for DELETE and UPDATE. It is supported for SELECT statements, as well as for DELETE and UPDATE.
The first row has the row number 1, and is calculated before ordering and grouping the result set, The first row has the row number 1, and is calculated before ordering and grouping the result set,
but after evaluating index conditions (even when the index conditions are specified in an outer query). but after evaluating index conditions (even when the index conditions are specified in an outer query).
...@@ -5335,10 +5335,10 @@ SELECT CUME_DIST() OVER (PARTITION BY CATEGORY ORDER BY ID), * FROM TEST; ...@@ -5335,10 +5335,10 @@ SELECT CUME_DIST() OVER (PARTITION BY CATEGORY ORDER BY ID), * FROM TEST;
" "
"Functions (Window)","NTILE"," "Functions (Window)","NTILE","
NTILE(int) OVER windowNameOrSpecification NTILE(long) OVER windowNameOrSpecification
"," ","
Distributes the rows into a specified number of groups. Distributes the rows into a specified number of groups.
Number of groups should be a positive integer value. Number of groups should be a positive long value.
NTILE returns the 1-based number of the group to which the current row belongs. NTILE returns the 1-based number of the group to which the current row belongs.
First groups will have more rows if number of rows is not divisible by number of groups. First groups will have more rows if number of rows is not divisible by number of groups.
For example, if 5 rows are distributed into 2 groups this function returns 1 for the first 3 row and 2 for the last 2 rows. For example, if 5 rows are distributed into 2 groups this function returns 1 for the first 3 row and 2 for the last 2 rows.
......
...@@ -21,6 +21,16 @@ Change Log ...@@ -21,6 +21,16 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>PR #1601: Return BIGINT from ROWNUM(), ROW_NUMBER() and rank functions
</li>
<li>PR #1599: cleanup StringUtils.cache
</li>
<li>PR #1598: Minor changes in parser and documentation
</li>
<li>PR #1597: Remove SysProperties.CHECK preconditions around simple assertions
</li>
<li>PR #1596: Improve SQL Standard compliance in LOB precision parsing
</li>
<li>Issue #1594: DBSettings.optimizeIsNull and dead code in IndexCursor.getMax() <li>Issue #1594: DBSettings.optimizeIsNull and dead code in IndexCursor.getMax()
</li> </li>
<li>PR #1591: Use multi-catch java 7 language construction to simplify code <li>PR #1591: Use multi-catch java 7 language construction to simplify code
......
...@@ -17,6 +17,7 @@ import org.h2.message.DbException; ...@@ -17,6 +17,7 @@ import org.h2.message.DbException;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.table.TableView; import org.h2.table.TableView;
import org.h2.util.MathUtils;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -60,7 +61,7 @@ public abstract class Prepared { ...@@ -60,7 +61,7 @@ public abstract class Prepared {
* already read, {@code >0} if object is stored and its id is not yet read. * already read, {@code >0} if object is stored and its id is not yet read.
*/ */
private int persistedObjectId; private int persistedObjectId;
private int currentRowNumber; private long currentRowNumber;
private int rowScanCount; private int rowScanCount;
/** /**
* Common table expressions (CTE) in queries require us to create temporary views, * Common table expressions (CTE) in queries require us to create temporary views,
...@@ -356,7 +357,7 @@ public abstract class Prepared { ...@@ -356,7 +357,7 @@ public abstract class Prepared {
* *
* @param rowNumber the row number * @param rowNumber the row number
*/ */
public void setCurrentRowNumber(int rowNumber) { public void setCurrentRowNumber(long rowNumber) {
if ((++rowScanCount & 127) == 0) { if ((++rowScanCount & 127) == 0) {
checkCanceled(); checkCanceled();
} }
...@@ -369,7 +370,7 @@ public abstract class Prepared { ...@@ -369,7 +370,7 @@ public abstract class Prepared {
* *
* @return the row number * @return the row number
*/ */
public int getCurrentRowNumber() { public long getCurrentRowNumber() {
return currentRowNumber; return currentRowNumber;
} }
...@@ -380,7 +381,9 @@ public abstract class Prepared { ...@@ -380,7 +381,9 @@ public abstract class Prepared {
if ((currentRowNumber & 127) == 0) { if ((currentRowNumber & 127) == 0) {
session.getDatabase().setProgress( session.getDatabase().setProgress(
DatabaseEventListener.STATE_STATEMENT_PROGRESS, DatabaseEventListener.STATE_STATEMENT_PROGRESS,
sqlStatement, currentRowNumber, 0); sqlStatement,
// TODO update interface
MathUtils.convertLongToInt(currentRowNumber), 0);
} }
} }
......
...@@ -400,7 +400,7 @@ public class Insert extends Prepared implements ResultTarget { ...@@ -400,7 +400,7 @@ public class Insert extends Prepared implements ResultTarget {
ArrayList<String> variableNames = new ArrayList<>( ArrayList<String> variableNames = new ArrayList<>(
duplicateKeyAssignmentMap.size()); duplicateKeyAssignmentMap.size());
Expression[] row = (currentRow == null) ? list.get(getCurrentRowNumber() - 1) Expression[] row = (currentRow == null) ? list.get((int) getCurrentRowNumber() - 1)
: new Expression[columns.length]; : new Expression[columns.length];
for (int i = 0; i < columns.length; i++) { for (int i = 0; i < columns.length; i++) {
String key = table.getSchema().getName() + "." + String key = table.getSchema().getName() + "." +
......
...@@ -438,7 +438,7 @@ public class Select extends Query { ...@@ -438,7 +438,7 @@ public class Select extends Query {
} }
private void gatherGroup(int columnCount, int stage) { private void gatherGroup(int columnCount, int stage) {
int rowNumber = 0; long rowNumber = 0;
setCurrentRowNumber(0); setCurrentRowNumber(0);
int sampleSize = getSampleSizeValue(session); int sampleSize = getSampleSizeValue(session);
ArrayList<Row>[] forUpdateRows = initForUpdateRows(); ArrayList<Row>[] forUpdateRows = initForUpdateRows();
...@@ -583,7 +583,7 @@ public class Select extends Query { ...@@ -583,7 +583,7 @@ public class Select extends Query {
limitRows = Long.MAX_VALUE; limitRows = Long.MAX_VALUE;
} }
} }
int rowNumber = 0; long rowNumber = 0;
setCurrentRowNumber(0); setCurrentRowNumber(0);
Index index = topTableFilter.getIndex(); Index index = topTableFilter.getIndex();
SearchRow first = null; SearchRow first = null;
...@@ -1665,7 +1665,7 @@ public class Select extends Query { ...@@ -1665,7 +1665,7 @@ public class Select extends Query {
*/ */
private abstract class LazyResultSelect extends LazyResult { private abstract class LazyResultSelect extends LazyResult {
int rowNumber; long rowNumber;
int columnCount; int columnCount;
LazyResultSelect(Expression[] expressions, int columnCount) { LazyResultSelect(Expression[] expressions, int columnCount) {
......
...@@ -11,7 +11,7 @@ import org.h2.message.DbException; ...@@ -11,7 +11,7 @@ import org.h2.message.DbException;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueInt; import org.h2.value.ValueLong;
/** /**
* Represents the ROWNUM function. * Represents the ROWNUM function.
...@@ -29,12 +29,12 @@ public class Rownum extends Expression { ...@@ -29,12 +29,12 @@ public class Rownum extends Expression {
@Override @Override
public Value getValue(Session session) { public Value getValue(Session session) {
return ValueInt.get(prepared.getCurrentRowNumber()); return ValueLong.get(prepared.getCurrentRowNumber());
} }
@Override @Override
public int getType() { public int getType() {
return Value.INT; return Value.LONG;
} }
@Override @Override
...@@ -59,12 +59,12 @@ public class Rownum extends Expression { ...@@ -59,12 +59,12 @@ public class Rownum extends Expression {
@Override @Override
public long getPrecision() { public long getPrecision() {
return ValueInt.PRECISION; return ValueLong.PRECISION;
} }
@Override @Override
public int getDisplaySize() { public int getDisplaySize() {
return ValueInt.DISPLAY_SIZE; return ValueLong.DISPLAY_SIZE;
} }
@Override @Override
......
...@@ -18,7 +18,7 @@ import org.h2.table.ColumnResolver; ...@@ -18,7 +18,7 @@ import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueDouble; import org.h2.value.ValueDouble;
import org.h2.value.ValueInt; import org.h2.value.ValueLong;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
/** /**
...@@ -184,7 +184,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -184,7 +184,7 @@ public class WindowFunction extends DataAnalysisOperation {
switch (type) { switch (type) {
case ROW_NUMBER: case ROW_NUMBER:
for (int i = 0, size = ordered.size(); i < size;) { for (int i = 0, size = ordered.size(); i < size;) {
result.put(ordered.get(i)[rowIdColumn].getInt(), ValueInt.get(++i)); result.put(ordered.get(i)[rowIdColumn].getInt(), ValueLong.get(++i));
} }
break; break;
case RANK: case RANK:
...@@ -231,7 +231,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -231,7 +231,7 @@ public class WindowFunction extends DataAnalysisOperation {
int nm = number - 1; int nm = number - 1;
v = nm == 0 ? ValueDouble.ZERO : ValueDouble.get((double) nm / (size - 1)); v = nm == 0 ? ValueDouble.ZERO : ValueDouble.get((double) nm / (size - 1));
} else { } else {
v = ValueInt.get(number); v = ValueLong.get(number);
} }
result.put(row[rowIdColumn].getInt(), v); result.put(row[rowIdColumn].getInt(), v);
} }
...@@ -260,20 +260,20 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -260,20 +260,20 @@ public class WindowFunction extends DataAnalysisOperation {
int size = orderedData.size(); int size = orderedData.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Value[] array = orderedData.get(i); Value[] array = orderedData.get(i);
int buckets = array[0].getInt(); long buckets = array[0].getLong();
if (buckets <= 0) { if (buckets <= 0) {
throw DbException.getInvalidValueException("number of tiles", buckets); throw DbException.getInvalidValueException("number of tiles", buckets);
} }
int perTile = size / buckets; long perTile = size / buckets;
int numLarger = size - perTile * buckets; long numLarger = size - perTile * buckets;
int largerGroup = numLarger * (perTile + 1); long largerGroup = numLarger * (perTile + 1);
int v; long v;
if (i >= largerGroup) { if (i >= largerGroup) {
v = (i - largerGroup) / perTile + numLarger + 1; v = (i - largerGroup) / perTile + numLarger + 1;
} else { } else {
v = i / (perTile + 1) + 1; v = i / (perTile + 1) + 1;
} }
result.put(orderedData.get(i)[last].getInt(), ValueInt.get(v)); result.put(orderedData.get(i)[last].getInt(), ValueLong.get(v));
} }
} }
...@@ -441,7 +441,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -441,7 +441,7 @@ public class WindowFunction extends DataAnalysisOperation {
case RANK: case RANK:
case DENSE_RANK: case DENSE_RANK:
case NTILE: case NTILE:
return Value.INT; return Value.LONG;
case PERCENT_RANK: case PERCENT_RANK:
case CUME_DIST: case CUME_DIST:
return Value.DOUBLE; return Value.DOUBLE;
...@@ -477,7 +477,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -477,7 +477,7 @@ public class WindowFunction extends DataAnalysisOperation {
case RANK: case RANK:
case DENSE_RANK: case DENSE_RANK:
case NTILE: case NTILE:
return ValueInt.PRECISION; return ValueLong.PRECISION;
case PERCENT_RANK: case PERCENT_RANK:
case CUME_DIST: case CUME_DIST:
return ValueDouble.PRECISION; return ValueDouble.PRECISION;
...@@ -499,7 +499,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -499,7 +499,7 @@ public class WindowFunction extends DataAnalysisOperation {
case RANK: case RANK:
case DENSE_RANK: case DENSE_RANK:
case NTILE: case NTILE:
return ValueInt.DISPLAY_SIZE; return ValueLong.DISPLAY_SIZE;
case PERCENT_RANK: case PERCENT_RANK:
case CUME_DIST: case CUME_DIST:
return ValueDouble.DISPLAY_SIZE; return ValueDouble.DISPLAY_SIZE;
......
...@@ -22,7 +22,8 @@ import org.h2.value.ValueNull; ...@@ -22,7 +22,8 @@ import org.h2.value.ValueNull;
import org.h2.value.ValueResultSet; import org.h2.value.ValueResultSet;
/** /**
* Implementation of the functions TABLE(..) and TABLE_DISTINCT(..). * Implementation of the functions TABLE(..), TABLE_DISTINCT(..), and
* UNNEST(..).
*/ */
public class TableFunction extends Function { public class TableFunction extends Function {
private final long rowCount; private final long rowCount;
......
...@@ -118,3 +118,12 @@ SELECT NTILE(X) OVER () FROM (SELECT * FROM SYSTEM_RANGE(1, 1)); ...@@ -118,3 +118,12 @@ SELECT NTILE(X) OVER () FROM (SELECT * FROM SYSTEM_RANGE(1, 1));
SELECT NTILE(X) OVER (ORDER BY X RANGE CURRENT ROW) FROM (SELECT * FROM SYSTEM_RANGE(1, 1)); SELECT NTILE(X) OVER (ORDER BY X RANGE CURRENT ROW) FROM (SELECT * FROM SYSTEM_RANGE(1, 1));
> exception SYNTAX_ERROR_1 > exception SYNTAX_ERROR_1
SELECT NTILE(100000000000) OVER (ORDER BY X) FROM (SELECT * FROM SYSTEM_RANGE(1, 4));
> NTILE(100000000000) OVER (ORDER BY X)
> -------------------------------------
> 1
> 2
> 3
> 4
> rows: 4
...@@ -804,4 +804,4 @@ qualification opportunity jumping exploited unacceptable vrs duplicated ...@@ -804,4 +804,4 @@ qualification opportunity jumping exploited unacceptable vrs duplicated
queryparser tokenized freeze factorings recompilation unenclosed rfe dsync queryparser tokenized freeze factorings recompilation unenclosed rfe dsync
econd irst bcef ordinality nord unnest econd irst bcef ordinality nord unnest
analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan
corrupts splitted disruption unintentional octets corrupts splitted disruption unintentional octets preconditions
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论