This is an automated email from the ASF dual-hosted git repository.
vjasani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/master by this push:
new db0fef1160 PHOENIX-7654 Restrict BSON datatype in composite PK as last
part of the pk column (#2212)
db0fef1160 is described below
commit db0fef1160585682d6004aebe2e353f69efd1780
Author: Rahul Kumar <[email protected]>
AuthorDate: Tue Jul 8 04:04:59 2025 +0530
PHOENIX-7654 Restrict BSON datatype in composite PK as last part of the pk
column (#2212)
---
.../apache/phoenix/exception/SQLExceptionCode.java | 4 ++
.../org/apache/phoenix/schema/MetaDataClient.java | 13 +++++++
.../org/apache/phoenix/end2end/AlterTableIT.java | 25 ++++++++++++
.../java/org/apache/phoenix/end2end/Bson4IT.java | 44 ++++++++++++++++++++++
4 files changed, 86 insertions(+)
diff --git
a/phoenix-core-client/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
b/phoenix-core-client/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
index f9492003f3..c85395ad2f 100644
---
a/phoenix-core-client/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
+++
b/phoenix-core-client/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
@@ -238,8 +238,12 @@ public enum SQLExceptionCode {
VARBINARY_IN_ROW_KEY(1005, "42J03",
"The VARBINARY/ARRAY type can only be used as the last part of a
multi-part row key. "
+ "For Binary types, you can use VARBINARY_ENCODED for early part
of multi-part row key."),
+ BSON_IN_ROW_KEY(1157, "42J03",
+ "The BSON type can only be used as the last part of a multi-part row
key."),
NOT_NULLABLE_COLUMN_IN_ROW_KEY(1006, "42J04", "Only nullable columns may
be added to primary key."),
VARBINARY_LAST_PK(1015, "42J04", "Cannot add column to table when the last
PK column is of type VARBINARY or ARRAY."),
+ BSON_LAST_PK(1156, "42J04",
+ "Cannot add column to table when the last PK column is of type BSON."),
NULLABLE_FIXED_WIDTH_LAST_PK(1023, "42J04", "Cannot add column to table
when the last PK column is nullable and fixed width."),
CANNOT_MODIFY_VIEW_PK(1036, "42J04", "Cannot modify the primary key of a
VIEW if last PK column of parent is variable length."),
BASE_TABLE_COLUMN(1037, "42J04", "Cannot modify columns of base table used
by tenant-specific tables."),
diff --git
a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 18d4cdb7fc..5b9498644f 100644
---
a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++
b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -283,6 +283,7 @@ import org.apache.phoenix.schema.PTable.ViewType;
import org.apache.phoenix.schema.stats.GuidePostsKey;
import org.apache.phoenix.schema.stats.StatisticsUtil;
import org.apache.phoenix.schema.task.Task;
+import org.apache.phoenix.schema.types.PBson;
import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.types.PDate;
import org.apache.phoenix.schema.types.PLong;
@@ -3287,6 +3288,13 @@ public class MetaDataClient {
.setTableName(tableName)
.setColumnName(column.getName().getString())
.build().buildException();
+ } else if (colDef.getDataType() == PBson.INSTANCE &&
SchemaUtil.isPKColumn(column)
+ && pkColumnsIterator.hasNext()) {
+ throw new
SQLExceptionInfo.Builder(SQLExceptionCode.BSON_IN_ROW_KEY)
+ .setSchemaName(schemaName)
+ .setTableName(tableName)
+ .setColumnName(column.getName().getString())
+ .build().buildException();
}
if (column.getFamilyName() != null) {
familyNames.put(
@@ -4633,6 +4641,11 @@ public class MetaDataClient {
throw new
SQLExceptionInfo.Builder(SQLExceptionCode.VARBINARY_LAST_PK)
.setColumnName(lastPK.getName().getString()).build().buildException();
}
+ // Disallow adding columns if the last column in the
primary key is BSON.
+ if (lastPK.getDataType() == PBson.INSTANCE) {
+ throw new
SQLExceptionInfo.Builder(SQLExceptionCode.BSON_LAST_PK)
+
.setColumnName(lastPK.getName().getString()).build().buildException();
+ }
// Disallow adding columns if last column in the primary
key is fixed width
// and nullable.
if (lastPK.isNullable() &&
lastPK.getDataType().isFixedWidth()) {
diff --git
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index 5648d0409c..5f20ac6518 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -155,6 +155,31 @@ public class AlterTableIT extends ParallelStatsDisabledIT {
}
}
+ @Test
+ public void testAlterTableWithBSONKey() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ conn.setAutoCommit(false);
+
+ String ddl = "CREATE TABLE " + dataTableFullName +
+ " (a_string varchar not null, a_bson BSON not null, col1 integer"
+
+ " CONSTRAINT pk PRIMARY KEY (a_string, a_bson)) " +
tableDDLOptions;
+ createTestTable(getUrl(), ddl);
+
+ conn.createStatement().execute("ALTER TABLE " + dataTableFullName + "
SET DISABLE_WAL = true");
+
+ try {
+ ddl = "ALTER TABLE " + dataTableFullName + " ADD b_string VARCHAR
NULL PRIMARY KEY";
+ PreparedStatement stmt = conn.prepareStatement(ddl);
+ stmt.execute();
+ fail("Should have caught bad alter.");
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.BSON_LAST_PK.getErrorCode(),
e.getErrorCode());
+ } finally {
+ conn.close();
+ }
+ }
+
@Test
public void testDropSystemTable() throws Exception {
Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/Bson4IT.java
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/Bson4IT.java
index 8c15854200..c20a7bbd23 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/Bson4IT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/Bson4IT.java
@@ -33,6 +33,7 @@ import java.util.Collection;
import java.util.Properties;
import org.apache.hadoop.hbase.util.Pair;
+import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
import org.apache.phoenix.schema.types.PDouble;
@@ -43,6 +44,7 @@ import org.bson.BsonDouble;
import org.bson.BsonNull;
import org.bson.BsonString;
import org.bson.RawBsonDocument;
+import org.junit.Assume;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
@@ -59,6 +61,7 @@ import static
org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -993,6 +996,47 @@ public class Bson4IT extends ParallelStatsDisabledIT {
}
}
+ @Test
+ public void testIndexingONBsonNotAllowed() throws Exception {
+ Assume.assumeTrue(this.coveredIndex && this.columnEncoded);
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ String tableName = generateUniqueName();
+ String indexName1 = "IDX1_" + tableName;
+ String indexName2 = "IDX2_" + tableName;
+ try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+ String ddl =
+ "CREATE TABLE " + tableName + " "
+ + "(PK1 VARCHAR NOT NULL, C1 VARCHAR, COL BSON "
+ + " CONSTRAINT pk PRIMARY KEY(PK1)) "
+ + (this.columnEncoded ? "" : "COLUMN_ENCODED_BYTES=0");
+ String indexDdl1 = "CREATE INDEX " + indexName1 + " ON " + tableName +
"(COL)";
+ String indexDdl2 = "CREATE INDEX " + indexName2 + " ON " + tableName +
"(C1)";
+
+ conn.createStatement().execute(ddl);
+ try {
+ conn.createStatement().execute(indexDdl1);
+ fail("Should have seen SQLExceptionCode.BSON_IN_ROW_KEY");
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.BSON_IN_ROW_KEY.getErrorCode(),
e.getErrorCode());
+ }
+
+ conn.createStatement().execute(indexDdl2);
+
+ String sample1 = getJsonString("json/sample_01.json");
+ String sample2 = getJsonString("json/sample_02.json");
+ String sample3 = getJsonString("json/sample_03.json");
+ BsonDocument bsonDocument1 = RawBsonDocument.parse(sample1);
+ BsonDocument bsonDocument2 = RawBsonDocument.parse(sample2);
+ BsonDocument bsonDocument3 = RawBsonDocument.parse(sample3);
+
+ upsertRows(conn, tableName, bsonDocument1, bsonDocument2, bsonDocument3);
+ conn.commit();
+ ResultSet rs = conn.createStatement().executeQuery("SELECT count(*) FROM
" + indexName2);
+ assertTrue(rs.next());
+ assertEquals(3, rs.getInt(1));
+ }
+ }
+
private static void upsertRowsWithBsonPkCol(Connection conn, String
tableName,
BsonDocument bsonDocument1,
BsonDocument bsonDocument2,