Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,81 @@ private Column<?> prepareGenericColumnValue(String columnName, DataType columnTy
}
}

public Map<String, DataType> getSupportedDataTypeMapForPrimaryKey() {
if (JdbcTestUtils.isMysql(rdbEngine)) {
return ImmutableMap.<String, DataType>builder()
.put("BOOLEAN", DataType.BOOLEAN)
.put("INT", DataType.INT)
.put("INT UNSIGNED", DataType.BIGINT)
.put("TINYINT", DataType.INT)
.put("SMALLINT", DataType.INT)
.put("MEDIUMINT", DataType.INT)
.put("BIGINT", DataType.BIGINT)
.put("FLOAT", DataType.FLOAT)
.put("DOUBLE", DataType.DOUBLE)
.put("CHAR(8)", DataType.TEXT)
.put("VARCHAR(512)", DataType.TEXT)
.build();
} else if (JdbcTestUtils.isPostgresql(rdbEngine)) {
return ImmutableMap.<String, DataType>builder()
.put("boolean", DataType.BOOLEAN)
.put("smallint", DataType.INT)
.put("integer", DataType.INT)
.put("bigint", DataType.BIGINT)
.put("real", DataType.FLOAT)
.put("double precision", DataType.DOUBLE)
.put("char(3)", DataType.TEXT)
.put("varchar(512)", DataType.TEXT)
.put("text", DataType.TEXT)
.build();
} else if (JdbcTestUtils.isOracle(rdbEngine)) {
return ImmutableMap.<String, DataType>builder()
.put("NUMERIC(15,0)", DataType.BIGINT)
.put("NUMERIC(15,2)", DataType.DOUBLE)
.put("FLOAT(53)", DataType.DOUBLE)
.put("BINARY_FLOAT", DataType.FLOAT)
.put("BINARY_DOUBLE", DataType.DOUBLE)
.put("CHAR(3)", DataType.TEXT)
.put("VARCHAR2(512)", DataType.TEXT)
.put("NCHAR(3)", DataType.TEXT)
.put("NVARCHAR2(512)", DataType.TEXT)
.build();
} else if (JdbcTestUtils.isSqlServer(rdbEngine)) {
return ImmutableMap.<String, DataType>builder()
.put("bit", DataType.BOOLEAN)
.put("tinyint", DataType.INT)
.put("smallint", DataType.INT)
.put("int", DataType.INT)
.put("bigint", DataType.BIGINT)
.put("real", DataType.FLOAT)
.put("float", DataType.DOUBLE)
.put("char(3)", DataType.TEXT)
.put("varchar(512)", DataType.TEXT)
.put("nchar(3)", DataType.TEXT)
.put("nvarchar(512)", DataType.TEXT)
.build();
} else if (JdbcTestUtils.isDb2(rdbEngine)) {
return ImmutableMap.<String, DataType>builder()
.put("SMALLINT", DataType.INT)
.put("INT", DataType.INT)
.put("BIGINT", DataType.BIGINT)
.put("REAL", DataType.FLOAT)
.put("FLOAT(24)", DataType.FLOAT)
.put("DOUBLE", DataType.DOUBLE)
.put("FLOAT", DataType.DOUBLE)
.put("FLOAT(25)", DataType.DOUBLE)
.put("CHAR(3)", DataType.TEXT)
.put("VARCHAR(512)", DataType.TEXT)
.put("GRAPHIC(3)", DataType.TEXT)
.put("VARGRAPHIC(32)", DataType.TEXT)
.put("NCHAR(3)", DataType.TEXT)
.put("NVARCHAR(32)", DataType.TEXT)
.build();
} else {
throw new AssertionError("Unsupported database engine: " + rdbEngine);
}
}

public void close() throws SQLException {
dataSource.close();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,194 @@
package com.scalar.db.storage.jdbc;

import static org.assertj.core.api.Assertions.assertThat;

import com.scalar.db.api.DistributedStorageVirtualTablesIntegrationTestBase;
import com.scalar.db.api.Put;
import com.scalar.db.api.Result;
import com.scalar.db.api.Scan;
import com.scalar.db.api.Scanner;
import com.scalar.db.api.TableMetadata;
import com.scalar.db.api.VirtualTableJoinType;
import com.scalar.db.config.DatabaseConfig;
import com.scalar.db.io.DataType;
import com.scalar.db.io.Key;
import com.scalar.db.util.ScalarDbUtils;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JdbcDatabaseVirtualTablesIntegrationTest
extends DistributedStorageVirtualTablesIntegrationTestBase {

private static final Logger logger =
LoggerFactory.getLogger(JdbcDatabaseVirtualTablesIntegrationTest.class);

private JdbcAdminImportTestUtils testUtils;
private RdbEngineStrategy rdbEngine;

@Override
protected Properties getProperties(String testName) {
return JdbcEnv.getProperties(testName);
Properties properties = JdbcEnv.getProperties(testName);
JdbcConfig config = new JdbcConfig(new DatabaseConfig(properties));
rdbEngine = RdbEngineFactory.create(config);
testUtils = new JdbcAdminImportTestUtils(properties);
return properties;
}

@DisabledIf("com.scalar.db.storage.jdbc.JdbcEnv#isSqlite")
@Test
public void createVirtualTable_WithImportedTableHavingVariousPrimaryKeyTypes_ShouldWorkProperly()
throws Exception {
for (Map.Entry<String, DataType> entry :
testUtils.getSupportedDataTypeMapForPrimaryKey().entrySet()) {
String dataTypeName = entry.getKey();
DataType dataType = entry.getValue();
String tableBaseName =
dataTypeName.replaceAll("[()]", "").replaceAll("[\\s,]", "_").toLowerCase();
String importedTableName = tableBaseName + "_imported";
String anotherTableName = tableBaseName + "_another";
String vtableInnerTableName = tableBaseName + "_vtable_inner";
String vtableLeftOuterTableName = tableBaseName + "_vtable_left_outer";

String createTableSql =
"CREATE TABLE "
+ rdbEngine.encloseFullTableName(namespace, importedTableName)
+ " ("
+ rdbEngine.enclose("pk")
+ " "
+ dataTypeName
+ " PRIMARY KEY"
+ (JdbcEnv.isDb2() ? " NOT NULL" : "")
+ ","
+ rdbEngine.enclose("col1")
+ " VARCHAR(100))";

try {
// Create a left source table to be imported
testUtils.execute(createTableSql);

// Import the left source table
admin.importTable(namespace, importedTableName, Collections.emptyMap());

// Create a right source table
admin.createTable(
namespace,
anotherTableName,
TableMetadata.newBuilder()
.addColumn("pk", dataType)
.addColumn("col2", DataType.TEXT)
.addPartitionKey("pk")
.build());

// Create a virtual table that joins the above two source tables with different join types
admin.createVirtualTable(
namespace,
vtableInnerTableName,
namespace,
importedTableName,
namespace,
anotherTableName,
VirtualTableJoinType.INNER);
admin.createVirtualTable(
namespace,
vtableLeftOuterTableName,
namespace,
importedTableName,
namespace,
anotherTableName,
VirtualTableJoinType.LEFT_OUTER);

// Verify that the virtual tables are created successfully
TableMetadata expectedMetadata =
TableMetadata.newBuilder()
.addColumn("pk", dataType)
.addColumn("col1", DataType.TEXT)
.addColumn("col2", DataType.TEXT)
.addPartitionKey("pk")
.build();
assertThat(admin.getTableMetadata(namespace, vtableInnerTableName))
.isEqualTo(expectedMetadata);
assertThat(admin.getTableMetadata(namespace, vtableLeftOuterTableName))
.isEqualTo(expectedMetadata);

// Put data into the virtual table
Key partitionKey1 = getPartitionKey(dataType, 1);
Key partitionKey2 = getPartitionKey(dataType, 2);
storage.put(
Put.newBuilder()
.namespace(namespace)
.table(vtableInnerTableName)
.partitionKey(partitionKey1)
.textValue("col1", "value1")
.textValue("col2", "value2")
.build());
storage.put(
Put.newBuilder()
.namespace(namespace)
.table(vtableInnerTableName)
.partitionKey(partitionKey2)
.textValue("col1", "value3")
.textValue("col2", "value4")
.build());

// Scan data from the virtual table and verify
try (Scanner scanner =
storage.scan(
Scan.newBuilder().namespace(namespace).table(vtableInnerTableName).all().build())) {
List<Result> results = scanner.all();
assertThat(results).hasSize(2);

// Verify results in any order
assertThat(results)
.anySatisfy(
result -> {
Assertions.<Key>assertThat(
ScalarDbUtils.getPartitionKey(result, expectedMetadata))
.isEqualTo(partitionKey1);
assertThat(result.getText("col1")).isEqualTo("value1");
assertThat(result.getText("col2")).isEqualTo("value2");
})
.anySatisfy(
result -> {
Assertions.<Key>assertThat(
ScalarDbUtils.getPartitionKey(result, expectedMetadata))
.isEqualTo(partitionKey2);
assertThat(result.getText("col1")).isEqualTo("value3");
assertThat(result.getText("col2")).isEqualTo("value4");
});
}
} finally {
// Drop the created tables
admin.dropTable(namespace, vtableInnerTableName, true);
admin.dropTable(namespace, vtableLeftOuterTableName, true);
admin.dropTable(namespace, anotherTableName, true);
admin.dropTable(namespace, importedTableName, true);
}
}
}

private Key getPartitionKey(DataType dataType, int index) {
switch (dataType) {
case BOOLEAN:
return Key.ofBoolean("pk", index == 1);
case INT:
return Key.ofInt("pk", index);
case BIGINT:
return Key.ofBigInt("pk", index);
case FLOAT:
return Key.ofFloat("pk", (float) index);
case DOUBLE:
return Key.ofDouble("pk", index);
case TEXT:
return Key.ofText("pk", String.valueOf(index * 100));
default:
throw new AssertionError("Unsupported data type: " + dataType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@DisabledIf("isSqlite")
@DisabledIf("com.scalar.db.storage.jdbc.JdbcEnv#isSqlite")
public class JdbcSchemaLoaderImportIntegrationTest extends SchemaLoaderImportIntegrationTestBase {

private static final Logger logger =
Expand Down Expand Up @@ -196,11 +196,6 @@ public void afterAll() {
}
}

@SuppressWarnings("unused")
private static boolean isSqlite() {
return JdbcEnv.isSqlite();
}

@Override
protected void waitForDifferentSessionDdl() {
if (JdbcTestUtils.isYugabyte(rdbEngine)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ public abstract class DistributedStorageVirtualTablesIntegrationTestBase {
private static final String RIGHT_SOURCE_TABLE = "right_source_table";
private static final String VIRTUAL_TABLE = "virtual_table";

private DistributedStorageAdmin admin;
private DistributedStorage storage;
private String namespace;
protected DistributedStorageAdmin admin;
protected DistributedStorage storage;
protected String namespace;

@BeforeAll
public void beforeAll() throws Exception {
Expand Down
Loading