Skip to content

Commit

Permalink
Merge pull request #3481 from katzyn/interval
Browse files Browse the repository at this point in the history
Add support for standard interval literals with precision
  • Loading branch information
katzyn committed Apr 9, 2022
2 parents d5329a7 + 3b8f9f1 commit e82a9e5
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 99 deletions.
14 changes: 13 additions & 1 deletion h2/src/docsrc/html/changelog.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ <h1>Change Log</h1>

<h2>Next Version (unreleased)</h2>
<ul>
<li>PR #3481: Add support for standard interval literals with precision
</li>
<li>Issue #3471: TRUNCATE TABLE seems to corrupt the Database file only after SHUTDOWN DEFRAG
</li>
<li>Issue #3473: Possible memory leak in 2.1.210
</li>
<li>PR #3464 / Issue #3457: increase max length of VAR* types
</li>
<li>PR #3460: fix bug in readStoreHeader()
</li>
<li>PR #3458: Add performance tests for SQLite
</li>
<li>Issue #1808: Occasional NPE in concurrent update of LOB
</li>
<li>Issue #3439: Cannot use enum values in JSON without explicit casts
Expand All @@ -32,7 +44,7 @@ <h2>Next Version (unreleased)</h2>
<li>Issue #3414: H2 2.1.210: Query with Parameters throws NPE at
org.h2.command.query.Query.getParameterValues(Query.java:449)
</li>
<li>Issue #3413: Parser can't parse REFERENCES NOT NULL
<li>Issue #3413: Parser can't parse REFERENCES &#8230; NOT NULL
</li>
<li>Issue #3410: OOME with nested derived tables
</li>
Expand Down
2 changes: 1 addition & 1 deletion h2/src/docsrc/html/performance.html
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ <h4>SQLite</h4>
SQLite 3.36.0.3, configured to use <a href="https://sqlite.org/wal.html">WAL</a> and with
<a href="https://sqlite.org/pragma.html#pragma_synchronous"><code>synchronous=NORMAL</code></a> was tested in a
separate, less reliable run. A rough estimate is that SQLite performs approximately 2-5x worse in the simple benchmarks,
which perform simple work in the database, resulting in a low work-per-transaction ration. SQLite becomes competitive as
which perform simple work in the database, resulting in a low work-per-transaction ratio. SQLite becomes competitive as
the complexity of the database interactions increases. The results seemed to vary drastically across machine, and more
reliable results should be obtained. Benchmark on your production hardware.
</p>
Expand Down
78 changes: 7 additions & 71 deletions h2/src/main/org/h2/command/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -5491,78 +5491,14 @@ private Expression readInterval() {
}
String s = token.value(session).getString();
read();
IntervalQualifier qualifier;
switch (currentTokenType) {
case YEAR:
read();
if (readIf(TO)) {
read(MONTH);
qualifier = IntervalQualifier.YEAR_TO_MONTH;
} else {
qualifier = IntervalQualifier.YEAR;
}
break;
case MONTH:
read();
qualifier = IntervalQualifier.MONTH;
break;
case DAY:
read();
if (readIf(TO)) {
switch (currentTokenType) {
case HOUR:
qualifier = IntervalQualifier.DAY_TO_HOUR;
break;
case MINUTE:
qualifier = IntervalQualifier.DAY_TO_MINUTE;
break;
case SECOND:
qualifier = IntervalQualifier.DAY_TO_SECOND;
break;
default:
throw intervalDayError();
}
read();
} else {
qualifier = IntervalQualifier.DAY;
}
break;
case HOUR:
read();
if (readIf(TO)) {
switch (currentTokenType) {
case MINUTE:
qualifier = IntervalQualifier.HOUR_TO_MINUTE;
break;
case SECOND:
qualifier = IntervalQualifier.HOUR_TO_SECOND;
break;
default:
throw intervalHourError();
}
read();
} else {
qualifier = IntervalQualifier.HOUR;
}
break;
case MINUTE:
read();
if (readIf(TO)) {
read(SECOND);
qualifier = IntervalQualifier.MINUTE_TO_SECOND;
} else {
qualifier = IntervalQualifier.MINUTE;
}
break;
case SECOND:
read();
qualifier = IntervalQualifier.SECOND;
break;
default:
throw intervalQualifierError();
}
TypeInfo typeInfo = readIntervalQualifier();
try {
return ValueExpression.get(IntervalUtils.parseInterval(qualifier, negative, s));
ValueInterval interval = IntervalUtils.parseInterval(
IntervalQualifier.valueOf(typeInfo.getValueType() - Value.INTERVAL_YEAR), negative, s);
if (typeInfo.getDeclaredPrecision() != -1L || typeInfo.getDeclaredScale() != -1) {
return TypedValueExpression.get(interval.castTo(typeInfo, session), typeInfo);
}
return ValueExpression.get(interval);
} catch (Exception e) {
throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2, e, "INTERVAL", s);
}
Expand Down
3 changes: 2 additions & 1 deletion h2/src/main/org/h2/mvstore/db/LobStorageMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,8 @@ public void cleanup(long oldestVersionToKeep) {
MVStore.TxCounter txCounter = mvStore.registerVersionUsage();
try {
LobRemovalInfo lobRemovalInfo;
while ((lobRemovalInfo = pendingLobRemovals.poll()) != null && lobRemovalInfo.version < oldestVersionToKeep) {
while ((lobRemovalInfo = pendingLobRemovals.poll()) != null
&& lobRemovalInfo.version < oldestVersionToKeep) {
doRemoveLob(lobRemovalInfo.mapId, lobRemovalInfo.lobId);
}
if (lobRemovalInfo != null) {
Expand Down
47 changes: 34 additions & 13 deletions h2/src/main/org/h2/res/help.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2400,105 +2400,126 @@ INTERVAL '1-2' YEAR TO MONTH
"

"Literals","INTERVAL YEAR","
INTERVAL [-|+] '[-|+]yearInt' YEAR
INTERVAL [-|+] '[-|+]yearInt' YEAR [ ( precisionInt ) ]
","
An INTERVAL YEAR literal.
If precision is specified it should be from 1 to 18.
","
INTERVAL '10' YEAR
"

"Literals","INTERVAL MONTH","
INTERVAL [-|+] '[-|+]monthInt' MONTH
INTERVAL [-|+] '[-|+]monthInt' MONTH [ ( precisionInt ) ]
","
An INTERVAL MONTH literal.
If precision is specified it should be from 1 to 18.
","
INTERVAL '10' MONTH
"

"Literals","INTERVAL DAY","
INTERVAL [-|+] '[-|+]dayInt' DAY
INTERVAL [-|+] '[-|+]dayInt' DAY [ ( precisionInt ) ]
","
An INTERVAL DAY literal.
If precision is specified it should be from 1 to 18.
","
INTERVAL '10' DAY
"

"Literals","INTERVAL HOUR","
INTERVAL [-|+] '[-|+]hourInt' HOUR
INTERVAL [-|+] '[-|+]hourInt' HOUR [ ( precisionInt ) ]
","
An INTERVAL HOUR literal.
If precision is specified it should be from 1 to 18.
","
INTERVAL '10' HOUR
"

"Literals","INTERVAL MINUTE","
INTERVAL [-|+] '[-|+]minuteInt' MINUTE
INTERVAL [-|+] '[-|+]minuteInt' MINUTE [ ( precisionInt ) ]
","
An INTERVAL MINUTE literal.
If precision is specified it should be from 1 to 18.
","
INTERVAL '10' MINUTE
"

"Literals","INTERVAL SECOND","
INTERVAL [-|+] '[-|+]secondInt[.nnnnnnnnn]' SECOND
INTERVAL [-|+] '[-|+]secondInt[.nnnnnnnnn]'
SECOND [ ( precisionInt [, fractionalPrecisionInt ] ) ]
","
An INTERVAL SECOND literal.
If precision is specified it should be from 1 to 18.
If fractional seconds precision is specified it should be from 0 to 9.
","
INTERVAL '10.123' SECOND
"

"Literals","INTERVAL YEAR TO MONTH","
INTERVAL [-|+] '[-|+]yearInt-monthInt' YEAR TO MONTH
INTERVAL [-|+] '[-|+]yearInt-monthInt' YEAR [ ( precisionInt ) ] TO MONTH
","
An INTERVAL YEAR TO MONTH literal.
If leading field precision is specified it should be from 1 to 18.
","
INTERVAL '1-6' YEAR TO MONTH
"

"Literals","INTERVAL DAY TO HOUR","
INTERVAL [-|+] '[-|+]dayInt hoursInt' DAY TO HOUR
INTERVAL [-|+] '[-|+]dayInt hoursInt' DAY [ ( precisionInt ) ] TO HOUR
","
An INTERVAL DAY TO HOUR literal.
If leading field precision is specified it should be from 1 to 18.
","
INTERVAL '10 11' DAY TO HOUR
"

"Literals","INTERVAL DAY TO MINUTE","
INTERVAL [-|+] '[-|+]dayInt hh:mm' DAY TO MINUTE
INTERVAL [-|+] '[-|+]dayInt hh:mm' DAY [ ( precisionInt ) ] TO MINUTE
","
An INTERVAL DAY TO MINUTE literal.
If leading field precision is specified it should be from 1 to 18.
","
INTERVAL '10 11:12' DAY TO MINUTE
"

"Literals","INTERVAL DAY TO SECOND","
INTERVAL [-|+] '[-|+]dayInt hh:mm:ss[.nnnnnnnnn]' DAY TO SECOND
INTERVAL [-|+] '[-|+]dayInt hh:mm:ss[.nnnnnnnnn]' DAY [ ( precisionInt ) ]
TO SECOND [ ( fractionalPrecisionInt ) ]
","
An INTERVAL DAY TO SECOND literal.
If leading field precision is specified it should be from 1 to 18.
If fractional seconds precision is specified it should be from 0 to 9.
","
INTERVAL '10 11:12:13.123' DAY TO SECOND
"

"Literals","INTERVAL HOUR TO MINUTE","
INTERVAL [-|+] '[-|+]hh:mm' HOUR TO MINUTE
INTERVAL [-|+] '[-|+]hh:mm' HOUR [ ( precisionInt ) ] TO MINUTE
","
An INTERVAL HOUR TO MINUTE literal.
If leading field precision is specified it should be from 1 to 18.
","
INTERVAL '10:11' HOUR TO MINUTE
"

"Literals","INTERVAL HOUR TO SECOND","
INTERVAL [-|+] '[-|+]hh:mm:ss[.nnnnnnnnn]' HOUR TO SECOND
INTERVAL [-|+] '[-|+]hh:mm:ss[.nnnnnnnnn]' HOUR [ ( precisionInt ) ]
TO SECOND [ ( fractionalPrecisionInt ) ]
","
An INTERVAL HOUR TO SECOND literal.
If leading field precision is specified it should be from 1 to 18.
If fractional seconds precision is specified it should be from 0 to 9.
","
INTERVAL '10:11:12.123' HOUR TO SECOND
"

"Literals","INTERVAL MINUTE TO SECOND","
INTERVAL [-|+] '[-|+]mm:ss[.nnnnnnnnn]' MINUTE TO SECOND
INTERVAL [-|+] '[-|+]mm:ss[.nnnnnnnnn]' MINUTE [ ( precisionInt ) ]
TO SECOND [ ( fractionalPrecisionInt ) ]
","
An INTERVAL MINUTE TO SECOND literal.
If leading field precision is specified it should be from 1 to 18.
If fractional seconds precision is specified it should be from 0 to 9.
","
INTERVAL '11:12.123' MINUTE TO SECOND
"
Expand Down
5 changes: 3 additions & 2 deletions h2/src/main/org/h2/table/InformationSchemaTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -1975,10 +1975,11 @@ private void routines(SessionLocal session, ArrayList<Row> rows, String catalog)
} else {
routineType = "FUNCTION";
}
String javaClassName = alias.getJavaClassName();
routines(session, rows, catalog, mainSchemaName, collation, schemaName, name,
name + '_' + (i + 1), routineType, admin ? alias.getSource() : null,
alias.getJavaClassName() + '.' + alias.getJavaMethodName(), typeInfo,
alias.isDeterministic(), alias.getComment());
javaClassName != null ? javaClassName + '.' + alias.getJavaMethodName() : null,
typeInfo, alias.isDeterministic(), alias.getComment());
}
} else {
routines(session, rows, catalog, mainSchemaName, collation, schemaName, name, name, "AGGREGATE",
Expand Down
5 changes: 3 additions & 2 deletions h2/src/test/org/h2/test/db/TestLob.java
Original file line number Diff line number Diff line change
Expand Up @@ -1581,7 +1581,7 @@ private void testLimitsLarge(byte[] b, String s, ValueLob v) throws IOException
assertEquals(s, IOUtils.readStringAndClose(v.getReader(), -1));
}
}

public void testConcurrentSelectAndUpdate() throws SQLException, InterruptedException {
deleteDb("lob");
try (JdbcConnection conn1 = (JdbcConnection) getConnection("lob")) {
Expand All @@ -1605,7 +1605,8 @@ public void testConcurrentSelectAndUpdate() throws SQLException, InterruptedExce
try {
String update = "update t1 set ver = ver + 1 where id = 1";
try (PreparedStatement ps = conn2.prepareStatement(update)) {
while (!Thread.currentThread().isInterrupted() && System.nanoTime() - startTimeNs < 10_000_000_000L) {
while (!Thread.currentThread().isInterrupted()
&& System.nanoTime() - startTimeNs < 10_000_000_000L) {
ps.executeUpdate();
}
}
Expand Down
3 changes: 3 additions & 0 deletions h2/src/test/org/h2/test/scripts/datatypes/interval.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1100,3 +1100,6 @@ SELECT T1, T2, (T1 - T2) YEAR TO MONTH, (T2 - T1) YEAR TO MONTH FROM (VALUES

SELECT (DATE '2010-01-02' - DATE '2000-01-01') YEAR;
>> INTERVAL '10' YEAR

VALUES INTERVAL '100' YEAR(2);
> exception INVALID_DATETIME_CONSTANT_2
30 changes: 22 additions & 8 deletions h2/src/test/org/h2/test/scripts/ddl/createAlias.sql
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,44 @@ SELECT MY_SQRT(-1.0) MS, SQRT(NULL) S;
> NaN null
> rows: 1

CREATE ALIAS MY_SUM AS 'int sum(int a, int b) { return a + b; }';
> ok

CALL MY_SUM(1, 2);
>> 3

SCRIPT NOPASSWORDS NOSETTINGS NOVERSION;
> SCRIPT
> ----------------------------------------------------------------
> ----------------------------------------------------------------------------------
> CREATE USER IF NOT EXISTS "SA" PASSWORD '' ADMIN;
> CREATE FORCE ALIAS "PUBLIC"."MY_SQRT" FOR 'java.lang.Math.sqrt';
> rows (ordered): 2
> CREATE FORCE ALIAS "PUBLIC"."MY_SUM" AS 'int sum(int a, int b) { return a + b; }';
> rows (ordered): 3

SELECT SPECIFIC_NAME, ROUTINE_NAME, ROUTINE_TYPE, DATA_TYPE, ROUTINE_BODY, EXTERNAL_NAME, EXTERNAL_LANGUAGE,
SELECT SPECIFIC_NAME, ROUTINE_NAME, ROUTINE_TYPE, DATA_TYPE, ROUTINE_BODY, ROUTINE_DEFINITION,
EXTERNAL_NAME, EXTERNAL_LANGUAGE,
IS_DETERMINISTIC, REMARKS FROM INFORMATION_SCHEMA.ROUTINES;
> SPECIFIC_NAME ROUTINE_NAME ROUTINE_TYPE DATA_TYPE ROUTINE_BODY EXTERNAL_NAME EXTERNAL_LANGUAGE IS_DETERMINISTIC REMARKS
> ------------- ------------ ------------ ---------------- ------------ ------------------- ----------------- ---------------- -------
> MY_SQRT_1 MY_SQRT FUNCTION DOUBLE PRECISION EXTERNAL java.lang.Math.sqrt JAVA NO null
> rows: 1
> SPECIFIC_NAME ROUTINE_NAME ROUTINE_TYPE DATA_TYPE ROUTINE_BODY ROUTINE_DEFINITION EXTERNAL_NAME EXTERNAL_LANGUAGE IS_DETERMINISTIC REMARKS
> ------------- ------------ ------------ ---------------- ------------ --------------------------------------- ------------------- ----------------- ---------------- -------
> MY_SQRT_1 MY_SQRT FUNCTION DOUBLE PRECISION EXTERNAL null java.lang.Math.sqrt JAVA NO null
> MY_SUM_1 MY_SUM FUNCTION INTEGER EXTERNAL int sum(int a, int b) { return a + b; } null JAVA NO null
> rows: 2

SELECT SPECIFIC_NAME, ORDINAL_POSITION, PARAMETER_MODE, IS_RESULT, AS_LOCATOR, PARAMETER_NAME, DATA_TYPE,
PARAMETER_DEFAULT FROM INFORMATION_SCHEMA.PARAMETERS;
> SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE IS_RESULT AS_LOCATOR PARAMETER_NAME DATA_TYPE PARAMETER_DEFAULT
> ------------- ---------------- -------------- --------- ---------- -------------- ---------------- -----------------
> MY_SQRT_1 1 IN NO NO P1 DOUBLE PRECISION null
> rows: 1
> MY_SUM_1 1 IN NO NO P1 INTEGER null
> MY_SUM_1 2 IN NO NO P2 INTEGER null
> rows: 3

DROP ALIAS MY_SQRT;
> ok

DROP ALIAS MY_SUM;
> ok

CREATE SCHEMA TEST_SCHEMA;
> ok

Expand Down
2 changes: 2 additions & 0 deletions h2/src/tools/org/h2/build/doc/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -848,3 +848,5 @@ orientation eternal consideration erased fedc npgsql powers fffd uencode ampersa
entirely skeleton discouraged pearson coefficient squares covariance mytab debuggers fonts glyphs
filestore backstop tie breaker lockable lobtx btx waiter accounted aiobe spf resolvers generators
accidental wbr subtree recognising supplementary happier hasn officially rnrn sonatype abandoned ldt odt
ver wal rough configuring xerial seemed journaling cited occasional worse pragma interactions journal approximately
drastically competitive

0 comments on commit e82a9e5

Please sign in to comment.