Unverified 提交 56407e6f authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #989 from katzyn/range_table

Fix more issues with range table and improve its documentation
......@@ -37,12 +37,27 @@ of all tables in the database as well as the current settings.
<h2 id="range_table" class="notranslate">Range Table</h2>
<p>
The range table is a dynamic system table that contains all values from a start to an end value.
The table contains one column called X. Both the start and end values are included in the result.
Non-zero step value may be also specified, default is 1.
Start value, end value, and optional step value are converted to BIGINT data type.
The table contains one column called X.
If start value is greater than end value and step is positive the result is empty.
If start value is less than end value and step is negative the result is empty too.
If start value is equal to end value the result contains only start value.
Start value, start value plus step, start value plus step multiplied by two and so on are included in result.
If step is positive the last value is less than or equal to the specified end value.
If step in negative the last value is greater than or equal to the specified end value.
The table is used as follows:
</p>
<p>Example:</p>
<p>Examples:</p>
<pre>
SELECT X FROM SYSTEM_RANGE(1, 10);
-- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
SELECT X FROM SYSTEM_RANGE(1, 10, 2);
-- 1, 3, 5, 7, 9
SELECT X FROM SYSTEM_RANGE(1, 10, -1);
-- No rows
SELECT X FROM SYSTEM_RANGE(10, 2, -2);
-- 10, 8, 6, 4, 2
</pre>
<!-- [close] { --></div></td></tr></table><!-- } --><!-- analytics --></body></html>
......@@ -90,7 +90,7 @@ public class HashIndex extends BaseIndex {
@Override
public long getRowCount(Session session) {
return getRowCountApproximation();
return rows.size();
}
@Override
......
......@@ -47,20 +47,34 @@ public class RangeIndex extends BaseIndex {
@Override
public Cursor find(Session session, SearchRow first, SearchRow last) {
long min = rangeTable.getMin(session), start = min;
long max = rangeTable.getMax(session), end = max;
long min = rangeTable.getMin(session);
long max = rangeTable.getMax(session);
long step = rangeTable.getStep(session);
try {
start = Math.max(min, first == null ? min : first.getValue(0).getLong());
long v = first.getValue(0).getLong();
if (step > 0) {
if (v > min) {
min += (v - min + step - 1) / step * step;
}
} else if (v > max) {
max = v;
}
} catch (Exception e) {
// error when converting the value - ignore
}
try {
end = Math.min(max, last == null ? max : last.getValue(0).getLong());
long v = last.getValue(0).getLong();
if (step > 0) {
if (v < max) {
max = v;
}
} else if (v < min) {
min -= (min - v - step - 1) / step * step;
}
} catch (Exception e) {
// error when converting the value - ignore
}
return new RangeCursor(session, start, end, step);
return new RangeCursor(session, min, max, step);
}
@Override
......@@ -108,7 +122,7 @@ public class RangeIndex extends BaseIndex {
@Override
public long getRowCount(Session session) {
return rangeTable.getRowCountApproximation();
return rangeTable.getRowCount(session);
}
@Override
......
......@@ -3,6 +3,80 @@
-- Initial Developer: H2 Group
--
explain select * from system_range(1, 2) where x=x+1 and x=1;
> PLAN
> ---------------------------------------------------------------------------------------------------------------------------------
> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 2) /* PUBLIC.RANGE_INDEX: X = 1 */ WHERE ((X = 1) AND (X = (X + 1))) AND (1 = (X + 1))
> rows: 1
explain select * from system_range(1, 2) where not (x = 1 and x*2 = 2);
> PLAN
> -------------------------------------------------------------------------------------------------------
> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 2) /* PUBLIC.RANGE_INDEX */ WHERE (X <> 1) OR ((X * 2) <> 2)
> rows: 1
explain select * from system_range(1, 10) where (NOT x >= 5);
> PLAN
> ------------------------------------------------------------------------------------------
> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 10) /* PUBLIC.RANGE_INDEX: X < 5 */ WHERE X < 5
> rows: 1
select (select t1.x from system_range(1,1) t2) from system_range(1,1) t1;
> SELECT T1.X FROM SYSTEM_RANGE(1, 1) T2 /* PUBLIC.RANGE_INDEX */ /* scanCount: 2 */
> ----------------------------------------------------------------------------------
> 1
> rows: 1
EXPLAIN PLAN FOR SELECT * FROM SYSTEM_RANGE(1, 20);
> PLAN
> -----------------------------------------------------------------------
> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 20) /* PUBLIC.RANGE_INDEX */
> rows: 1
select sum(x) from system_range(2, 1000) r where
not exists(select * from system_range(2, 32) r2 where r.x>r2.x and mod(r.x, r2.x)=0);
> SUM(X)
> ------
> 76127
> rows: 1
SELECT COUNT(*) FROM SYSTEM_RANGE(0, 2111222333);
> COUNT(*)
> ----------
> 2111222334
> rows: 1
select * from system_range(2, 100) r where
not exists(select * from system_range(2, 11) r2 where r.x>r2.x and mod(r.x, r2.x)=0);
> X
> --
> 11
> 13
> 17
> 19
> 2
> 23
> 29
> 3
> 31
> 37
> 41
> 43
> 47
> 5
> 53
> 59
> 61
> 67
> 7
> 71
> 73
> 79
> 83
> 89
> 97
> rows: 25
SELECT * FROM SYSTEM_RANGE(1, 10) ORDER BY 1;
> X
> --
......@@ -118,3 +192,57 @@ SELECT * FROM SYSTEM_RANGE(2, 1, 0);
SELECT COUNT(*) FROM SYSTEM_RANGE(2, 1, 0);
> exception
SELECT * FROM SYSTEM_RANGE(1, 8, 2);
> X
> -
> 1
> 3
> 5
> 7
> rows: 4
SELECT * FROM SYSTEM_RANGE(1, 8, 2) WHERE X = 2;
> X
> -
> rows: 0
SELECT COUNT(*) FROM SYSTEM_RANGE(1, 8, 2) WHERE X = 2;
>> 0
SELECT * FROM SYSTEM_RANGE(1, 8, 2) WHERE X BETWEEN 2 AND 6;
> X
> -
> 3
> 5
> rows: 2
SELECT COUNT(*) FROM SYSTEM_RANGE(1, 8, 2) WHERE X BETWEEN 2 AND 6;
>> 2
SELECT * FROM SYSTEM_RANGE(8, 1, -2) ORDER BY X DESC;
> X
> -
> 8
> 6
> 4
> 2
> rows (ordered): 4
SELECT * FROM SYSTEM_RANGE(8, 1, -2) WHERE X = 3;
> X
> -
> rows: 0
SELECT COUNT(*) FROM SYSTEM_RANGE(8, 1, -2) WHERE X = 3;
>> 0
SELECT * FROM SYSTEM_RANGE(8, 1, -2) WHERE X BETWEEN 3 AND 7 ORDER BY 1 DESC;
> X
> -
> 6
> 4
> rows (ordered): 2
SELECT COUNT(*) FROM SYSTEM_RANGE(8, 1, -2) WHERE X BETWEEN 3 AND 7;
>> 2
......@@ -1950,24 +1950,6 @@ create table test as select 1, space(10) from dual where 1=0 union all select x,
drop table test;
> ok
explain select * from system_range(1, 2) where x=x+1 and x=1;
> PLAN
> ---------------------------------------------------------------------------------------------------------------------------------
> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 2) /* PUBLIC.RANGE_INDEX: X = 1 */ WHERE ((X = 1) AND (X = (X + 1))) AND (1 = (X + 1))
> rows: 1
explain select * from system_range(1, 2) where not (x = 1 and x*2 = 2);
> PLAN
> -------------------------------------------------------------------------------------------------------
> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 2) /* PUBLIC.RANGE_INDEX */ WHERE (X <> 1) OR ((X * 2) <> 2)
> rows: 1
explain select * from system_range(1, 10) where (NOT x >= 5);
> PLAN
> ------------------------------------------------------------------------------------------
> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 10) /* PUBLIC.RANGE_INDEX: X < 5 */ WHERE X < 5
> rows: 1
CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255));
> ok
......@@ -3042,12 +3024,6 @@ SELECT t1.ID, (SELECT t1.id || ':' || AVG(t2.ID) FROM X t2) FROM X t1;
drop table x;
> ok
select (select t1.x from system_range(1,1) t2) from system_range(1,1) t1;
> SELECT T1.X FROM SYSTEM_RANGE(1, 1) T2 /* PUBLIC.RANGE_INDEX */ /* scanCount: 2 */
> ----------------------------------------------------------------------------------
> 1
> rows: 1
create table test(id int primary key, name varchar);
> ok
......@@ -5872,12 +5848,6 @@ EXPLAIN PLAN FOR SELECT LEFT(NAME, 2) FROM TEST;
> SELECT LEFT(NAME, 2) FROM PUBLIC.TEST /* PUBLIC.TEST.tableScan */
> rows: 1
EXPLAIN PLAN FOR SELECT * FROM SYSTEM_RANGE(1, 20);
> PLAN
> -----------------------------------------------------------------------
> SELECT SYSTEM_RANGE.X FROM SYSTEM_RANGE(1, 20) /* PUBLIC.RANGE_INDEX */
> rows: 1
SELECT * FROM test t1 inner join test t2 on t1.id=t2.id and t2.name is not null where t1.id=1;
> ID NAME ID NAME
> -- ----- -- -----
......@@ -6358,54 +6328,6 @@ SELECT * FROM TEST;
DROP TABLE TEST;
> ok
--- range ----------------------------------------------------------------------------------------------
--import java.math.*;
--int s=0;for(int i=2;i<=1000;i++)
--s+=BigInteger.valueOf(i).isProbablePrime(10000)?i:0;s;
select sum(x) from system_range(2, 1000) r where
not exists(select * from system_range(2, 32) r2 where r.x>r2.x and mod(r.x, r2.x)=0);
> SUM(X)
> ------
> 76127
> rows: 1
SELECT COUNT(*) FROM SYSTEM_RANGE(0, 2111222333);
> COUNT(*)
> ----------
> 2111222334
> rows: 1
select * from system_range(2, 100) r where
not exists(select * from system_range(2, 11) r2 where r.x>r2.x and mod(r.x, r2.x)=0);
> X
> --
> 11
> 13
> 17
> 19
> 2
> 23
> 29
> 3
> 31
> 37
> 41
> 43
> 47
> 5
> 53
> 59
> 61
> 67
> 7
> 71
> 73
> 79
> 83
> 89
> 97
> rows: 25
--- syntax errors ----------------------------------------------------------------------------------------------
CREATE SOMETHING STRANGE;
> exception
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论