Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IDENTITY() and SCOPE_IDENTITY() to LEGACY mode #3381

Merged
merged 2 commits into from Jan 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions h2/src/docsrc/html/changelog.html
Expand Up @@ -21,6 +21,8 @@ <h1>Change Log</h1>

<h2>Next Version (unreleased)</h2>
<ul>
<li>PR #3381: Add IDENTITY() and SCOPE_IDENTITY() to LEGACY mode
</li>
<li>Issue #3376: Data cannot be read after insert of clob data > MAX_LENGTH_INPLACE_LOB with data change delta table
</li>
<li>PR #3377: Add -webExternalNames setting and fix WebServer.getConnection()
Expand Down
1 change: 1 addition & 0 deletions h2/src/docsrc/html/features.html
Expand Up @@ -883,6 +883,7 @@ <h3>LEGACY Compatibility Mode</h3>
</li><li>Attempt to reference a non-unique set of columns from a referential constraint
will create an UNIQUE constraint on them automatically.
</li><li>Unsafe comparison operators between numeric and boolean values are allowed.
</li><li>IDENTITY() and SCOPE_IDENTITY() are supported, but both are implemented like SCOPE_IDENTITY()
</li></ul>

<h3>DB2 Compatibility Mode</h3>
Expand Down
1 change: 1 addition & 0 deletions h2/src/main/org/h2/engine/Mode.java
Expand Up @@ -478,6 +478,7 @@ public enum CharPadding {
// Legacy identity and sequence features
mode.identityClause = true;
mode.updateSequenceOnManualIdentityInsertion = true;
mode.takeInsertedIdentity = true;
mode.identityColumnsHaveDefaultOnNull = true;
mode.nextvalAndCurrvalPseudoColumns = true;
// Legacy DML features
Expand Down
69 changes: 69 additions & 0 deletions h2/src/main/org/h2/mode/FunctionsLegacy.java
@@ -0,0 +1,69 @@
/*
* Copyright 2004-2022 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.mode;

import java.util.HashMap;

import org.h2.engine.SessionLocal;
import org.h2.expression.Expression;
import org.h2.message.DbException;
import org.h2.value.TypeInfo;
import org.h2.value.Value;

/**
* This class implements some legacy functions not available in Regular mode.
*/
public class FunctionsLegacy extends ModeFunction {

private static final HashMap<String, FunctionInfo> FUNCTIONS = new HashMap<>();

private static final int IDENTITY = 6001;

private static final int SCOPE_IDENTITY = IDENTITY + 1;

static {
FUNCTIONS.put("IDENTITY", new FunctionInfo("IDENTITY", IDENTITY, 0, Value.BIGINT, true, false));
FUNCTIONS.put("SCOPE_IDENTITY",
new FunctionInfo("SCOPE_IDENTITY", SCOPE_IDENTITY, 0, Value.BIGINT, true, false));
}

/**
* Returns mode-specific function for a given name, or {@code null}.
*
* @param upperName
* the upper-case name of a function
* @return the function with specified name or {@code null}
*/
public static FunctionsLegacy getFunction(String upperName) {
FunctionInfo info = FUNCTIONS.get(upperName);
if (info != null) {
return new FunctionsLegacy(info);
}
return null;
}

private FunctionsLegacy(FunctionInfo info) {
super(info);
}

@Override
public Value getValue(SessionLocal session) {
switch (info.type) {
case IDENTITY:
case SCOPE_IDENTITY:
return session.getLastIdentity().convertTo(type);
default:
throw DbException.getInternalError("type=" + info.type);
}
}

@Override
public Expression optimize(SessionLocal session) {
type = TypeInfo.getTypeInfo(info.returnDataType);
return this;
}

}
2 changes: 2 additions & 0 deletions h2/src/main/org/h2/mode/ModeFunction.java
Expand Up @@ -49,6 +49,8 @@ public static ModeFunction getFunction(Database database, String name) {

private static ModeFunction getCompatibilityModeFunction(String name, ModeEnum modeEnum) {
switch (modeEnum) {
case LEGACY:
return FunctionsLegacy.getFunction(name);
case DB2:
case Derby:
return FunctionsDB2Derby.getFunction(name);
Expand Down
2 changes: 1 addition & 1 deletion h2/src/test/org/h2/test/scripts/TestScript.java
Expand Up @@ -206,7 +206,7 @@ public void test() throws Exception {
"file-read", "file-write", "greatest", "h2version", "identity",
"ifnull", "last-insert-id", "least", "link-schema", "lock-mode", "lock-timeout",
"memory-free", "memory-used", "nextval", "nullif", "nvl2",
"readonly", "rownum", "scope-identity", "session-id",
"readonly", "rownum", "session-id",
"table", "transaction-id", "trim_array", "truncate-value", "unnest" }) {
testScript("functions/system/" + s + ".sql");
}
Expand Down
30 changes: 30 additions & 0 deletions h2/src/test/org/h2/test/scripts/functions/system/identity.sql
Expand Up @@ -2,3 +2,33 @@
-- and the EPL 1.0 (https://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--

CREATE TABLE TEST(ID BIGINT GENERATED BY DEFAULT AS IDENTITY, V INT);
> ok

INSERT INTO TEST(V) VALUES 10;
> update count: 1

VALUES IDENTITY();
> exception FUNCTION_NOT_FOUND_1

VALUES SCOPE_IDENTITY();
> exception FUNCTION_NOT_FOUND_1

SET MODE LEGACY;
> ok

INSERT INTO TEST(V) VALUES 20;
> update count: 1

VALUES IDENTITY();
>> 2

VALUES SCOPE_IDENTITY();
>> 2

SET MODE REGULAR;
> ok

DROP TABLE TEST;
> ok

This file was deleted.