From 20cc4da38802c88a59a73bd3d62621430476eee7 Mon Sep 17 00:00:00 2001 From: GroundWu <1175416256@qq.com> Date: Thu, 31 Oct 2024 19:38:01 +0800 Subject: [PATCH 1/8] add fulltext index dml case --- .../rpc/ObTableFullTextIndexTest.java | 331 ++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java diff --git a/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java b/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java new file mode 100644 index 00000000..f077bc3d --- /dev/null +++ b/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java @@ -0,0 +1,331 @@ +package com.alipay.oceanbase.rpc; + +import com.alipay.oceanbase.rpc.exception.ObTableException; +import com.alipay.oceanbase.rpc.mutation.result.MutationResult; +import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; +import com.alipay.oceanbase.rpc.table.ObTable; +import com.alipay.oceanbase.rpc.util.ObTableClientTestUtil; +import com.google.protobuf.MapEntry; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.nio.ByteBuffer; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; +import java.util.Map; + +import static com.alipay.oceanbase.rpc.mutation.MutationFactory.colVal; +import static com.alipay.oceanbase.rpc.mutation.MutationFactory.row; + +public class ObTableFullTextIndexTest { + ObTableClient client; + String tableName = "tbl1"; + String ttlTableName = "ttl_tbl1"; + String createTableSQL = "CREATE TABLE IF NOT EXISTS tbl1(id INT, c2 INT, txt text, PRIMARY KEY (id), FULLTEXT INDEX full_idx1_tbl1(txt));"; + String createTTLTableSQL = "CREATE TABLE IF NOT EXISTS ttl_tbl1(id INT, c2 INT, txt text, expired_ts timestamp(6), PRIMARY KEY (id), FULLTEXT INDEX full_idx1_tbl1(txt)) TTL(expired_ts + INTERVAL 10 SECOND);;"; + String truncateTableSQL = "truncate table tbl1;"; + String truncateTTLTableSQL = "truncate table ttl_tbl1;"; + String dropTableSQL = "drop table tbl1"; + String idCol = "id"; + String c2Col = "c2"; + String txtCol = "txt"; + String expireTsCol = "expired_ts"; + @Before + public void setup() throws Exception { + executeSQL(createTableSQL); + executeSQL(createTTLTableSQL); + final ObTableClient obTableClient = ObTableClientTestUtil.newTestClient(); + obTableClient.init(); + this.client = obTableClient; + } + + @After + public void teardown() throws Exception { +// executeSQL(dropTableSQL); + } + + @Test + public void testInsert() throws Exception { + try{ + MutationResult res = client.insert(tableName).setRowKey(colVal(idCol, 1)) + .addMutateRow(row(colVal(txtCol, "OceanBase Database is a native, " + + "enterprise-level distributed database developed independently by the OceanBase team"))) + .execute(); + Assert.assertEquals(1, res.getAffectedRows()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testGet() throws Exception { + try{ + MutationResult insRes = client.insert(tableName).setRowKey(colVal(idCol, 3)) + .addMutateRow(row(colVal(txtCol, "OceanBase Database is a native, " + + "enterprise-level distributed database developed independently by the OceanBase team"))) + .execute(); + Assert.assertEquals(1, insRes.getAffectedRows()); + + Map res = client.get(tableName, new Object[] { 3 }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testDel() throws Exception { + try{ + MutationResult insRes = client.insert(tableName).setRowKey(colVal(idCol, 4)) + .addMutateRow(row(colVal(txtCol, "aaa asdjl asdjlakjsdl hello select new fine"))) + .execute(); + Assert.assertEquals(1, insRes.getAffectedRows()); + // get + Map res = client.get(tableName, new Object[] { 1 }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + // del + MutationResult delRes = client.delete(tableName).setRowKey(colVal(idCol, 1)).execute(); + Assert.assertEquals(1, delRes.getAffectedRows()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testUpd() throws Exception { + try{ + MutationResult insRes = client.insert(tableName).setRowKey(colVal(idCol, 5)) + .addMutateRow(row(colVal(txtCol, "aaa asdjl asdjlakjsdl hello select new fine"))) + .execute(); + Assert.assertEquals(1, insRes.getAffectedRows()); + // get + Map res = client.get(tableName, new Object[] { 5 }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + + // update with fulltext columns + System.out.println("update with fulltext column"); + MutationResult updRes = client.update(tableName).setRowKey(colVal(idCol, 5)) + .addMutateRow(row(colVal(txtCol, "The sun was setting on the horizon, casting a warm golden glow over the tranquil ocean. "))) + .execute(); + Assert.assertEquals(1, updRes.getAffectedRows()); + // get again + res = client.get(tableName, new Object[] { 5 }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + + // update with non-fulltext columns + System.out.println("update with non-fulltext column"); + updRes = client.update(tableName).setRowKey(colVal(idCol, 5)) + .addMutateRow(row(colVal(c2Col, 10))) + .execute(); + Assert.assertEquals(1, updRes.getAffectedRows()); + // get again + res = client.get(tableName, new Object[] { 5 }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + + // update all columns + System.out.println("update all column"); + updRes = client.update(tableName).setRowKey(colVal(idCol, 5)) + .addMutateRow(row(colVal(c2Col, 100), + colVal(txtCol, "As the day came to a close, the peaceful scene served as a reminder of the beauty and serenity that nature has to offer."))) + .execute(); + Assert.assertEquals(1, updRes.getAffectedRows()); + // get again + res = client.get(tableName, new Object[] { 5 }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testInsOrUpd() throws Exception { + try { + // insertup-insert + MutationResult insRes = client.insertOrUpdate(tableName).setRowKey(colVal(idCol, 6)) + .addMutateRow(row(colVal(txtCol, "The sun rose over the horizon, casting a warm glow across the meadow. "))) + .execute(); + Assert.assertEquals(1, insRes.getAffectedRows()); + // get + Map res = client.get(tableName, new Object[] { 6 }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + + // insertup-update with non fulltext column + MutationResult updRes = client.insertOrUpdate(tableName).setRowKey(colVal(idCol, 6)) + .addMutateRow(row(colVal(c2Col, 100))) + .execute(); + Assert.assertEquals(1, updRes.getAffectedRows()); + // get + res = client.get(tableName, new Object[] { 6 }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + // insertup-update with fulltext column + updRes = client.insertOrUpdate(tableName).setRowKey(colVal(idCol, 6)) + .addMutateRow(row(colVal(txtCol, " The birds chirped happily as they flew from tree to tree"))) + .execute(); + Assert.assertEquals(1, updRes.getAffectedRows()); + // get + res = client.get(tableName, new Object[] { 6 }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + + // insertup-update with all column + updRes = client.insertOrUpdate(tableName).setRowKey(colVal(idCol, 6)) + .addMutateRow(row(colVal(c2Col, 106), + colVal(txtCol, " The birds chirped happily as they flew from tree to tree"))) + .execute(); + Assert.assertEquals(1, updRes.getAffectedRows()); + // get + res = client.get(tableName, new Object[] { 6 }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + executeSQL(truncateTableSQL); + } + } + + @Test + public void testReplace() throws Exception { + try { + int id = 7; + // replace-insert + MutationResult insRes = client.replace(tableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, "The sun rose over the horizon, casting a warm glow across the meadow. "))) + .execute(); + Assert.assertEquals(1, insRes.getAffectedRows()); + // get + Map res = client.get(tableName, new Object[] { id }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + + // replace-conflict with non fulltext column + MutationResult updRes = client.replace(tableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(c2Col, 100))) + .execute(); + Assert.assertEquals(2, updRes.getAffectedRows()); + // get + res = client.get(tableName, new Object[] { id }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + // replace-conflict with fulltext column + updRes = client.replace(tableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, " The birds chirped happily as they flew from tree to tree"))) + .execute(); + Assert.assertEquals(2, updRes.getAffectedRows()); + // get + res = client.get(tableName, new Object[] { id }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + + // replace-conflict with all column + updRes = client.replace(tableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(c2Col, 100+id), + colVal(txtCol, " The birds chirped happily as they flew from tree to tree"))) + .execute(); + Assert.assertEquals(2, updRes.getAffectedRows()); + // get + res = client.get(tableName, new Object[] { id }, null); + for (Map.Entry entry: res.entrySet()) { + System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + executeSQL(truncateTableSQL); + } + } + + @Test + public void testTTLInsert() throws Exception { + try { + // 写入新行 + int id = 8; + Timestamp curTs = new Timestamp(System.currentTimeMillis()); + Timestamp expireTs = new Timestamp(System.currentTimeMillis() - 1000000); + MutationResult insRes = client.insert(ttlTableName).setRowKey(colVal(idCol, id + 1)) + .addMutateRow(row(colVal(expireTsCol, expireTs), + colVal(txtCol, "The sun rose over the horizon, casting a warm glow across the meadow. "))) + .execute(); + Assert.assertEquals(1, insRes.getAffectedRows()); + + insRes = client.insert(ttlTableName).setRowKey(colVal(idCol, id + 2)) + .addMutateRow(row(colVal(expireTsCol, curTs), + colVal(txtCol, "The birds chirped happily as they flew from tree to tree"))) + .execute(); + Assert.assertEquals(1, insRes.getAffectedRows()); + + // 过期,删除旧行,写入新行 + insRes = client.insert(ttlTableName).setRowKey(colVal(idCol, id + 1)) + .addMutateRow(row(colVal(expireTsCol, curTs), + colVal(txtCol, "Two roads diverged in a wood"))) + .execute(); + Assert.assertEquals(1, insRes.getAffectedRows()); + + // get + Map res = client.get(ttlTableName, new Object[]{id + 1}, null); + for (Map.Entry entry : res.entrySet()) { + System.out.println("key: " + entry.getKey() + " value: " + entry.getValue()); + } + + // 未过期 + // - insert操作 + try { + client.insert(ttlTableName).setRowKey(colVal(idCol, id + 2)) + .addMutateRow(row(colVal(expireTsCol, curTs), + colVal(txtCol, "I took the one less traveled by"))) + .execute(); + } catch (ObTableException e) { + Assert.assertEquals(ResultCodes.OB_ERR_PRIMARY_KEY_DUPLICATE.errorCode, e.getErrorCode()); + } + // - insertup操作 + insRes = client.insertOrUpdate(ttlTableName).setRowKey(colVal(idCol, id + 2)) + .addMutateRow(row(colVal(expireTsCol, curTs), + colVal(txtCol, "I took the one less traveled by"))) + .execute(); + Assert.assertEquals(1, insRes.getAffectedRows()); + + // get + res = client.get(ttlTableName, new Object[]{id + 2}, null); + for (Map.Entry entry : res.entrySet()) { + System.out.println("key: " + entry.getKey() + " value: " + entry.getValue()); + } + } catch(Exception e) { + e.printStackTrace(); + } finally { + // executeSQL(truncateTTLTableSQL); + } + } + + private void executeSQL(String createSQL) throws SQLException { + Connection connection = ObTableClientTestUtil.getConnection(); + Statement statement = connection.createStatement(); + statement.execute(createSQL); + } +} From 07ec67450df6b26df3ab5fd33b9ce9f4f44f6b85 Mon Sep 17 00:00:00 2001 From: GroundWu <1175416256@qq.com> Date: Tue, 5 Nov 2024 10:25:32 +0800 Subject: [PATCH 2/8] adapt fts query request --- .../oceanbase/rpc/ObClusterTableQuery.java | 6 ++ .../payload/impl/execute/ObIndexType.java | 42 +++++++++--- .../impl/execute/query/ObTableQuery.java | 28 ++++++-- .../rpc/table/AbstractTableQueryImpl.java | 7 ++ .../oceanbase/rpc/table/ObFTSParams.java | 64 +++++++++++++++++++ .../oceanbase/rpc/table/ObKVParams.java | 3 + .../oceanbase/rpc/table/ObKVParamsBase.java | 19 ++++-- .../oceanbase/rpc/table/api/TableQuery.java | 2 + .../rpc/ObTableFullTextIndexTest.java | 35 ++++++++++ .../query/ObTableQueryPayloadTest.java | 35 ++++++++++ 10 files changed, 222 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/alipay/oceanbase/rpc/table/ObFTSParams.java diff --git a/src/main/java/com/alipay/oceanbase/rpc/ObClusterTableQuery.java b/src/main/java/com/alipay/oceanbase/rpc/ObClusterTableQuery.java index 8afb323b..1c1e03e1 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/ObClusterTableQuery.java +++ b/src/main/java/com/alipay/oceanbase/rpc/ObClusterTableQuery.java @@ -240,4 +240,10 @@ public void setEntityType(ObTableEntityType entityType) { super.setEntityType(entityType); tableClientQuery.setEntityType(entityType); } + + @Override + public TableQuery setSearchText(String searchText) { + tableClientQuery.setSearchText(searchText); + return this; + } } diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/ObIndexType.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/ObIndexType.java index 9b766c36..d912d447 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/ObIndexType.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/ObIndexType.java @@ -21,16 +21,38 @@ import java.util.Map; public enum ObIndexType { - IndexTypeIsNot(0), IndexTypeNormalLocal(1), IndexTypeUniqueLocal(2), IndexTypeNormalGlobal(3), IndexTypeUniqueGlobal( - 4), IndexTypePrimary( - 5), IndexTypeDomainCtxcat( - 6), IndexTypeNormalGlobalLocalStorage( - 7), IndexTypeUniqueGlobalLocalStorage( - 8), IndexTypeSpatialLocal( - 10), IndexTypeSpatialGlobal( - 11), IndexTypeSpatialGlobalLocalStorage( - 12), IndexTypeMax( - 13); + IndexTypeIsNot(0), + IndexTypeNormalLocal(1), + IndexTypeUniqueLocal(2), + IndexTypeNormalGlobal(3), + IndexTypeUniqueGlobal(4), + IndexTypePrimary(5), + IndexTypeDomainCtxcat(6), + IndexTypeNormalGlobalLocalStorage(7), + IndexTypeUniqueGlobalLocalStorage(8), + IndexTypeSpatialLocal(10), + IndexTypeSpatialGlobal(11), + IndexTypeSpatialGlobalLocalStorage(12), + IndexTypeRowkeyDocIdLocal(13), + IndexTypeDocIdRowkeyLocal(14), + IndexTypeFtsIndexLocal(15), + IndexTypeFtsDocWordLocal(16), + /* + IndexTypeDocIdRowkeyGlobal(17), + IndexTypeFtsIndexGlobal(18), + IndexTypeFtsDocWordGlobal(19), + IndexTypeDocIdRowkeyGlobalLocalStorage(20), + IndexTypeFtsIndexGlobalLocalStorage(21), + IndexTypeFtsDocWordGlobalLocalStorage(22), + IndexTypeNormalMultivalueLocal(23), + IndexTypeUniqueMultivalueLocal(24), + IndexTypeVecRowkeyVidLocal(25), + IndexTypeVecVidRowkeyLocal(26), + IndexTypeVecDeltaBufferLocal(27), + IndexTypeVecIndexIdLocal(28), + IndexTypeVecIndexSnapshotDataLocal(29), + */ + IndexTypeMax(30); private int value; private static Map map = new HashMap(); diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java index 13371fcc..1e63a146 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java @@ -18,13 +18,15 @@ package com.alipay.oceanbase.rpc.protocol.payload.impl.execute.query; import com.alipay.oceanbase.rpc.exception.FeatureNotSupportedException; +import com.alipay.oceanbase.rpc.table.ObFTSParams; import com.alipay.oceanbase.rpc.table.ObHBaseParams; -import com.alipay.oceanbase.rpc.table.ObKVParams; +import com.alipay.oceanbase.rpc.table. ObKVParams; import com.alipay.oceanbase.rpc.protocol.payload.AbstractPayload; import com.alipay.oceanbase.rpc.protocol.payload.impl.ObObj; import com.alipay.oceanbase.rpc.protocol.payload.impl.ObRowKey; import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.aggregation.ObTableAggregationSingle; import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.aggregation.ObTableAggregationType; +import com.alipay.oceanbase.rpc.table.ObKVParamsBase; import com.alipay.oceanbase.rpc.util.Serialization; import io.netty.buffer.ByteBuf; @@ -71,7 +73,7 @@ public class ObTableQuery extends AbstractPayload { private List aggregations = new LinkedList<>(); - private ObKVParams obKVParams; + private ObKVParams obKVParams = null; public void adjustStartKey(List key) throws IllegalArgumentException { List keyRanges = getKeyRanges(); @@ -223,7 +225,7 @@ public byte[] encode() { idx += len; } - if (isHbaseQuery && obKVParams != null) { + if (obKVParams != null) { // hbaseQuery or FTSQuery will use obKVParams len = (int) obKVParams.getPayloadSize(); System.arraycopy(obKVParams.encode(), 0, bytes, idx, len); idx += len; @@ -290,7 +292,11 @@ public Object decode(ByteBuf buf) { String agg_column = Serialization.decodeVString(buf); this.aggregations.add(new ObTableAggregationSingle(ObTableAggregationType.fromByte(agg_type), agg_column)); } - if (isHbaseQuery) { + + buf.markReaderIndex(); + if (buf.readByte() > 0) { + // read pType if is exists + buf.resetReaderIndex(); obKVParams = new ObKVParams(); this.obKVParams.decode(buf); } @@ -325,7 +331,7 @@ public long getPayloadContentSize() { } else { contentSize += HTABLE_DUMMY_BYTES.length; } - if (isHbaseQuery && obKVParams != null) { + if (obKVParams != null) { contentSize += obKVParams.getPayloadSize(); } else { contentSize += HTABLE_DUMMY_BYTES.length; @@ -545,6 +551,18 @@ public void setObKVParams(ObKVParams obKVParams) { this.obKVParams = obKVParams; } + public void setSearchText(String searchText) { + if (isHbaseQuery) { + throw new FeatureNotSupportedException("Hbase query not support full text search currently"); + } + if (obKVParams == null) { + obKVParams = new ObKVParams(); + } + ObFTSParams ftsParams = (ObFTSParams)obKVParams.getObParams(ObKVParamsBase.paramType.FTS); + ftsParams.setSearchText(searchText); + obKVParams.setObParamsBase(ftsParams); + } + public ObKVParams getObKVParams() { return obKVParams; } diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/AbstractTableQueryImpl.java b/src/main/java/com/alipay/oceanbase/rpc/table/AbstractTableQueryImpl.java index eca0f246..72d9e39c 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/table/AbstractTableQueryImpl.java +++ b/src/main/java/com/alipay/oceanbase/rpc/table/AbstractTableQueryImpl.java @@ -23,6 +23,7 @@ import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.query.ObNewRange; import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.query.ObScanOrder; import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.query.ObTableQuery; +import com.alipay.oceanbase.rpc.table.api.Table; import com.alipay.oceanbase.rpc.table.api.TableQuery; import java.util.Arrays; @@ -184,6 +185,12 @@ public TableQuery setMaxResultSize(long maxResultSize) { return this; } + @Override + public TableQuery setSearchText(String searchText) { + this.tableQuery.setSearchText(searchText); + return this; + } + public String getIndexTableName() { return indexTableName; } diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/ObFTSParams.java b/src/main/java/com/alipay/oceanbase/rpc/table/ObFTSParams.java new file mode 100644 index 00000000..854074e3 --- /dev/null +++ b/src/main/java/com/alipay/oceanbase/rpc/table/ObFTSParams.java @@ -0,0 +1,64 @@ +/*- + * #%L + * com.oceanbase:obkv-table-client + * %% + * Copyright (C) 2021 - 2024 OceanBase + * %% + * OBKV Table Client Framework is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * #L% + */ + +package com.alipay.oceanbase.rpc.table; + +import com.alipay.oceanbase.rpc.util.Serialization; +import io.netty.buffer.ByteBuf; + +public class ObFTSParams extends ObKVParamsBase { + String searchText = null; + public ObFTSParams() { + pType = paramType.FTS; + } + + public paramType getType() { + return pType; + } + + public void setSearchText(String searchText) { + this.searchText = searchText; + } + + public String getSearchText() { return this.searchText; } + + public byte[] encode() { + byte[] bytes = new byte[(int) getPayloadContentSize()]; + int idx = 0; + byte[] b = new byte[] { (byte)pType.ordinal() }; + System.arraycopy(b, 0, bytes, idx, 1); + idx += 1; + int len = Serialization.getNeedBytes(searchText); + System.arraycopy(Serialization.encodeVString(searchText), 0, bytes, idx, len); + return bytes; + } + + public Object decode(ByteBuf buf) { + // pType is read by ObKVParams + this.searchText = Serialization.decodeVString(buf); + return this; + } + + public long getPayloadContentSize() { + return 1 /* pType*/ + Serialization.getNeedBytes(searchText); + } + + public String toString() { + return "ObFtsParams: {\n pType = " + pType + ", \n searchText = " + searchText + + "\n}\n"; + } +} diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/ObKVParams.java b/src/main/java/com/alipay/oceanbase/rpc/table/ObKVParams.java index 3b0a0bb8..f5964a41 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/table/ObKVParams.java +++ b/src/main/java/com/alipay/oceanbase/rpc/table/ObKVParams.java @@ -32,6 +32,9 @@ public ObKVParamsBase getObParams(ObKVParamsBase.paramType pType) { case HBase: return new ObHBaseParams(); case Redis: + throw new RuntimeException("Currently does not support redis type"); + case FTS: + return new ObFTSParams(); default: throw new RuntimeException("Currently does not support other types except HBase"); } diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/ObKVParamsBase.java b/src/main/java/com/alipay/oceanbase/rpc/table/ObKVParamsBase.java index 796e4cf9..453a2939 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/table/ObKVParamsBase.java +++ b/src/main/java/com/alipay/oceanbase/rpc/table/ObKVParamsBase.java @@ -17,20 +17,31 @@ package com.alipay.oceanbase.rpc.table; +import com.alipay.oceanbase.rpc.direct_load.protocol.payload.ObTableLoadClientStatus; import io.netty.buffer.ByteBuf; +import java.util.HashMap; +import java.util.Map; + public abstract class ObKVParamsBase { public enum paramType { - HBase((byte) 0), Redis((byte) 1); + HBase((byte) 0), Redis((byte) 1), FTS((byte) 2); private final byte value; + private static final Map map = new HashMap(); + + static { + for (paramType type : paramType.values()) { + map.put(type.ordinal(), type); + } + } + + public static paramType valueOf(int value) { return map.get(value); } paramType(byte value) { this.value = value; } - public byte getValue() { - return value; - } + public byte getValue() { return value; } } public int byteSize; diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/api/TableQuery.java b/src/main/java/com/alipay/oceanbase/rpc/table/api/TableQuery.java index 2f915327..a928a879 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/table/api/TableQuery.java +++ b/src/main/java/com/alipay/oceanbase/rpc/table/api/TableQuery.java @@ -199,4 +199,6 @@ public interface TableQuery { TableQuery setScanRangeColumns(String... columns); void clear(); + + TableQuery setSearchText(String searchText); } diff --git a/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java b/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java index f077bc3d..652325d3 100644 --- a/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java +++ b/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java @@ -3,6 +3,8 @@ import com.alipay.oceanbase.rpc.exception.ObTableException; import com.alipay.oceanbase.rpc.mutation.result.MutationResult; import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; +import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.query.ObTableQuery; +import com.alipay.oceanbase.rpc.stream.QueryResultSet; import com.alipay.oceanbase.rpc.table.ObTable; import com.alipay.oceanbase.rpc.util.ObTableClientTestUtil; import com.google.protobuf.MapEntry; @@ -323,6 +325,39 @@ public void testTTLInsert() throws Exception { } } + @Test + public void testFtsQuery() throws Exception { + try { + //sync query + QueryResultSet resultSet = client.query(tableName) + .setSearchText("native") + .indexName("full_idx1_tbl1") + .execute(); + while(resultSet.next()) { + Map row = resultSet.getRow(); + for (Map.Entry entry: row.entrySet()) { + System.out.println("colname: " + entry.getKey() + " \nvalue: " + entry.getValue()); + } + System.out.println(); + } + // async query + System.out.println("========async query:========="); + QueryResultSet asyncResultSet = client.query(tableName) + .indexName("full_idx1_tbl1") + .setSearchText("oceanbase") + .asyncExecute(); + while(asyncResultSet.next()) { + Map row = asyncResultSet.getRow(); + for (Map.Entry entry: row.entrySet()) { + System.out.println("colname: " + entry.getKey() + " \nvalue: " + entry.getValue()); + } + System.out.println(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + private void executeSQL(String createSQL) throws SQLException { Connection connection = ObTableClientTestUtil.getConnection(); Statement statement = connection.createStatement(); diff --git a/src/test/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQueryPayloadTest.java b/src/test/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQueryPayloadTest.java index b4f7ee8a..3c844f58 100644 --- a/src/test/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQueryPayloadTest.java +++ b/src/test/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQueryPayloadTest.java @@ -20,11 +20,15 @@ import com.alipay.oceanbase.rpc.protocol.payload.impl.*; import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.ObTableConsistencyLevel; import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.ObTableEntityType; +import com.alipay.oceanbase.rpc.table.ObFTSParams; import com.alipay.oceanbase.rpc.table.ObHBaseParams; import com.alipay.oceanbase.rpc.table.ObKVParams; +import com.alipay.oceanbase.rpc.table.ObKVParamsBase; import com.alipay.oceanbase.rpc.util.ObBytesString; +import com.sun.xml.internal.ws.wsdl.writer.document.ParamType; import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; +import org.junit.Assert; import org.junit.Test; import java.util.ArrayList; @@ -150,6 +154,37 @@ public void test_ObTableQueryResult() { buf.release(); } + @Test + public void testFtsParam() { + ObFTSParams ftsParams = new ObFTSParams(); + ftsParams.setSearchText("oceanbase"); + byte[] bytes = ftsParams.encode(); + ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer(); + buf.writeBytes(bytes); + ObFTSParams newFtsParams = new ObFTSParams(); + assertEquals(ftsParams.getType(), ObKVParamsBase.paramType.valueOf(buf.readByte())); + newFtsParams.decode(buf); + assertEquals(ftsParams.getSearchText(), newFtsParams.getSearchText()); + buf.release(); + } + + @Test + public void testFtsQuery() { + ObTableQuery obTableQuery = getObTableQuery(); + obTableQuery.setIndexName("ftx_idx"); + obTableQuery.setSearchText("oceanbase"); + byte[] bytes = obTableQuery.encode(); + ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer(); + buf.writeBytes(bytes); + + ObTableQuery newObTableQuery = new ObTableQuery(); + newObTableQuery.decode(buf); + ObKVParamsBase kv_params_base = newObTableQuery.getObKVParams().obKVParamsBase; + Assert.assertEquals(ObKVParamsBase.paramType.FTS, kv_params_base.getType()); + ObFTSParams fts_params = (ObFTSParams) kv_params_base; + Assert.assertEquals("oceanbase", fts_params.getSearchText()); + } + private ObTableQuery getObTableQuery() { ObTableQuery obTableQuery = new ObTableQuery(); obTableQuery.addKeyRange(getObNewRange()); From b494b202fe9a6789d2854a527f8a0be16a11e060 Mon Sep 17 00:00:00 2001 From: GroundWu <1175416256@qq.com> Date: Tue, 5 Nov 2024 20:54:30 +0800 Subject: [PATCH 3/8] adapt fulltext query --- .../payload/impl/execute/query/ObTableQuery.java | 10 +++++++--- .../oceanbase/rpc/table/ObTableClientQueryImpl.java | 4 ++++ .../alipay/oceanbase/rpc/ObTableFullTextIndexTest.java | 8 +++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java index 1e63a146..b0acfb6d 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java @@ -69,6 +69,7 @@ public class ObTableQuery extends AbstractPayload { private static final byte[] HTABLE_DUMMY_BYTES = new byte[] { 0x01, 0x00 }; private boolean isHbaseQuery = false; + private boolean isFTSQuery = true; private List scanRangeColumns = new LinkedList(); private List aggregations = new LinkedList<>(); @@ -552,18 +553,21 @@ public void setObKVParams(ObKVParams obKVParams) { } public void setSearchText(String searchText) { - if (isHbaseQuery) { + if (this.isHbaseQuery) { throw new FeatureNotSupportedException("Hbase query not support full text search currently"); } - if (obKVParams == null) { + if (this.obKVParams == null) { obKVParams = new ObKVParams(); } ObFTSParams ftsParams = (ObFTSParams)obKVParams.getObParams(ObKVParamsBase.paramType.FTS); ftsParams.setSearchText(searchText); - obKVParams.setObParamsBase(ftsParams); + this.obKVParams.setObParamsBase(ftsParams); + this.isFTSQuery = true; } public ObKVParams getObKVParams() { return obKVParams; } + + public boolean isFTSQuery() { return isFTSQuery; } } diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/ObTableClientQueryImpl.java b/src/main/java/com/alipay/oceanbase/rpc/table/ObTableClientQueryImpl.java index 8a274d18..6d42cdaf 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/table/ObTableClientQueryImpl.java +++ b/src/main/java/com/alipay/oceanbase/rpc/table/ObTableClientQueryImpl.java @@ -160,6 +160,10 @@ private AbstractQueryStreamResult commonExecute(InitQueryResultCallback Date: Mon, 11 Nov 2024 10:23:47 +0800 Subject: [PATCH 4/8] add fts query limit/offset case --- .../rpc/ObTableFullTextIndexTest.java | 613 ++++++++++++++---- 1 file changed, 490 insertions(+), 123 deletions(-) diff --git a/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java b/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java index 0f467854..e923bb1d 100644 --- a/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java +++ b/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java @@ -1,11 +1,15 @@ package com.alipay.oceanbase.rpc; import com.alipay.oceanbase.rpc.exception.ObTableException; +import com.alipay.oceanbase.rpc.mutation.*; +import com.alipay.oceanbase.rpc.mutation.result.BatchOperationResult; import com.alipay.oceanbase.rpc.mutation.result.MutationResult; import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes; import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.query.ObTableQuery; import com.alipay.oceanbase.rpc.stream.QueryResultSet; import com.alipay.oceanbase.rpc.table.ObTable; +import com.alipay.oceanbase.rpc.table.api.TableBatchOps; +import com.alipay.oceanbase.rpc.table.api.TableQuery; import com.alipay.oceanbase.rpc.util.ObTableClientTestUtil; import com.google.protobuf.MapEntry; import org.junit.After; @@ -18,6 +22,8 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; +import java.util.List; +import java.util.Locale; import java.util.Map; import static com.alipay.oceanbase.rpc.mutation.MutationFactory.colVal; @@ -25,11 +31,14 @@ public class ObTableFullTextIndexTest { ObTableClient client; - String tableName = "tbl1"; + String noPartTableName = "tbl1"; + String partTableName = "part_tbl1"; String ttlTableName = "ttl_tbl1"; - String createTableSQL = "CREATE TABLE IF NOT EXISTS tbl1(id INT, c2 INT, txt text, PRIMARY KEY (id), FULLTEXT INDEX full_idx1_tbl1(txt)) partition by key(id) partitions 3;"; - String createTTLTableSQL = "CREATE TABLE IF NOT EXISTS ttl_tbl1(id INT, c2 INT, txt text, expired_ts timestamp(6), PRIMARY KEY (id), FULLTEXT INDEX full_idx1_tbl1(txt)) TTL(expired_ts + INTERVAL 10 SECOND);;"; - String truncateTableSQL = "truncate table tbl1;"; + String createNoPartTableSQL = "CREATE TABLE IF NOT EXISTS tbl1(id INT, c2 INT, txt text, PRIMARY KEY (id), FULLTEXT INDEX full_idx1_tbl1(txt))"; + String createPartTableSQL = "CREATE TABLE IF NOT EXISTS part_tbl1(id INT, c2 INT, txt text, PRIMARY KEY (id), FULLTEXT INDEX full_idx1_tbl1(txt)) partition by key(id) partitions 3;"; + String createTTLTableSQL = "CREATE TABLE IF NOT EXISTS ttl_tbl1(id INT, c2 INT, txt text, expired_ts timestamp(6), PRIMARY KEY (id), FULLTEXT INDEX full_idx1_tbl1(txt)) TTL(expired_ts + INTERVAL 10 SECOND) partition by key(id) partitions 3;"; + String truncateNoPartTableSQL = "truncate table tbl1;"; + String truncatePartTableSQL = "truncate table part_tbl1;"; String truncateTTLTableSQL = "truncate table ttl_tbl1;"; String dropTableSQL = "drop table tbl1"; String idCol = "id"; @@ -38,7 +47,8 @@ public class ObTableFullTextIndexTest { String expireTsCol = "expired_ts"; @Before public void setup() throws Exception { - executeSQL(createTableSQL); + executeSQL(createNoPartTableSQL); + executeSQL(createPartTableSQL); executeSQL(createTTLTableSQL); final ObTableClient obTableClient = ObTableClientTestUtil.newTestClient(); obTableClient.init(); @@ -53,7 +63,8 @@ public void teardown() throws Exception { @Test public void testInsert() throws Exception { try{ - MutationResult res = client.insert(tableName).setRowKey(colVal(idCol, 1)) + int id = 1; + MutationResult res = client.insert(partTableName).setRowKey(colVal(idCol, id)) .addMutateRow(row(colVal(txtCol, "OceanBase Database is a native, " + "enterprise-level distributed database developed independently by the OceanBase team"))) .execute(); @@ -66,16 +77,19 @@ public void testInsert() throws Exception { @Test public void testGet() throws Exception { try{ - MutationResult insRes = client.insert(tableName).setRowKey(colVal(idCol, 3)) - .addMutateRow(row(colVal(txtCol, "OceanBase Database is a native, " + - "enterprise-level distributed database developed independently by the OceanBase team"))) + int id = 3; + String txt = "OceanBase Database is a native, " + + "enterprise-level distributed database developed independently by the OceanBase team"; + MutationResult insRes = client.insert(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, txt))) .execute(); Assert.assertEquals(1, insRes.getAffectedRows()); - Map res = client.get(tableName, new Object[] { 3 }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + Map res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(null, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); } catch (Exception e) { e.printStackTrace(); } @@ -84,18 +98,25 @@ public void testGet() throws Exception { @Test public void testDel() throws Exception { try{ - MutationResult insRes = client.insert(tableName).setRowKey(colVal(idCol, 4)) - .addMutateRow(row(colVal(txtCol, "aaa asdjl asdjlakjsdl hello select new fine"))) + int id = 4; + String txt = "aaa asdjl asdjlakjsdl hello select new fine"; + MutationResult insRes = client.insert(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, txt))) .execute(); Assert.assertEquals(1, insRes.getAffectedRows()); // get - Map res = client.get(tableName, new Object[] { 1 }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + Map res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(null, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); + // del - MutationResult delRes = client.delete(tableName).setRowKey(colVal(idCol, 1)).execute(); + MutationResult delRes = client.delete(partTableName).setRowKey(colVal(idCol, id)).execute(); Assert.assertEquals(1, delRes.getAffectedRows()); + // get + res = client.get(partTableName, new Object[] { id }, null); + Assert.assertTrue(res.isEmpty()); } catch (Exception e) { e.printStackTrace(); } @@ -104,52 +125,57 @@ public void testDel() throws Exception { @Test public void testUpd() throws Exception { try{ - MutationResult insRes = client.insert(tableName).setRowKey(colVal(idCol, 5)) - .addMutateRow(row(colVal(txtCol, "aaa asdjl asdjlakjsdl hello select new fine"))) + int id = 5; + String txt = "aaa asdjl asdjlakjsdl hello select new fine"; + MutationResult insRes = client.insert(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, txt))) .execute(); Assert.assertEquals(1, insRes.getAffectedRows()); // get - Map res = client.get(tableName, new Object[] { 5 }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + Map res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(null, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); // update with fulltext columns - System.out.println("update with fulltext column"); - MutationResult updRes = client.update(tableName).setRowKey(colVal(idCol, 5)) - .addMutateRow(row(colVal(txtCol, "The sun was setting on the horizon, casting a warm golden glow over the tranquil ocean. "))) + txt = "The sun was setting on the horizon, casting a warm golden glow over the tranquil ocean. "; + MutationResult updRes = client.update(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, txt))) .execute(); Assert.assertEquals(1, updRes.getAffectedRows()); // get again - res = client.get(tableName, new Object[] { 5 }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(null, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); // update with non-fulltext columns - System.out.println("update with non-fulltext column"); - updRes = client.update(tableName).setRowKey(colVal(idCol, 5)) + updRes = client.update(partTableName).setRowKey(colVal(idCol, id)) .addMutateRow(row(colVal(c2Col, 10))) .execute(); Assert.assertEquals(1, updRes.getAffectedRows()); // get again - res = client.get(tableName, new Object[] { 5 }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(10, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); // update all columns - System.out.println("update all column"); - updRes = client.update(tableName).setRowKey(colVal(idCol, 5)) + txt = "As the day came to a close, the peaceful scene served as a reminder of the beauty and serenity that nature has to offer."; + updRes = client.update(partTableName).setRowKey(colVal(idCol, id)) .addMutateRow(row(colVal(c2Col, 100), - colVal(txtCol, "As the day came to a close, the peaceful scene served as a reminder of the beauty and serenity that nature has to offer."))) + colVal(txtCol, txt))) .execute(); Assert.assertEquals(1, updRes.getAffectedRows()); // get again - res = client.get(tableName, new Object[] { 5 }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(100, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); } catch (Exception e) { e.printStackTrace(); } @@ -158,54 +184,63 @@ public void testUpd() throws Exception { @Test public void testInsOrUpd() throws Exception { try { + int id = 6; + String txt = "The sun rose over the horizon, casting a warm glow across the meadow. "; // insertup-insert - MutationResult insRes = client.insertOrUpdate(tableName).setRowKey(colVal(idCol, 6)) - .addMutateRow(row(colVal(txtCol, "The sun rose over the horizon, casting a warm glow across the meadow. "))) + MutationResult insRes = client.insertOrUpdate(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, txt))) .execute(); Assert.assertEquals(1, insRes.getAffectedRows()); // get - Map res = client.get(tableName, new Object[] { 6 }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + Map res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(null, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); // insertup-update with non fulltext column - MutationResult updRes = client.insertOrUpdate(tableName).setRowKey(colVal(idCol, 6)) + MutationResult updRes = client.insertOrUpdate(partTableName).setRowKey(colVal(idCol, id)) .addMutateRow(row(colVal(c2Col, 100))) .execute(); Assert.assertEquals(1, updRes.getAffectedRows()); // get - res = client.get(tableName, new Object[] { 6 }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(100, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); + // insertup-update with fulltext column - updRes = client.insertOrUpdate(tableName).setRowKey(colVal(idCol, 6)) - .addMutateRow(row(colVal(txtCol, " The birds chirped happily as they flew from tree to tree"))) + txt = "The birds chirped happily as they flew from tree to tree"; + updRes = client.insertOrUpdate(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, txt))) .execute(); Assert.assertEquals(1, updRes.getAffectedRows()); // get - res = client.get(tableName, new Object[] { 6 }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(100, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); // insertup-update with all column - updRes = client.insertOrUpdate(tableName).setRowKey(colVal(idCol, 6)) + txt = " The birds chirped happily as they flew from tree to tree"; + updRes = client.insertOrUpdate(partTableName).setRowKey(colVal(idCol, id)) .addMutateRow(row(colVal(c2Col, 106), - colVal(txtCol, " The birds chirped happily as they flew from tree to tree"))) + colVal(txtCol, txt))) .execute(); Assert.assertEquals(1, updRes.getAffectedRows()); // get - res = client.get(tableName, new Object[] { 6 }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(106, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); } catch (Exception e) { e.printStackTrace(); } finally { - executeSQL(truncateTableSQL); + executeSQL(truncatePartTableSQL); } } @@ -213,54 +248,62 @@ public void testInsOrUpd() throws Exception { public void testReplace() throws Exception { try { int id = 7; + String txt = "The sun rose over the horizon, casting a warm glow across the meadow. "; // replace-insert - MutationResult insRes = client.replace(tableName).setRowKey(colVal(idCol, id)) - .addMutateRow(row(colVal(txtCol, "The sun rose over the horizon, casting a warm glow across the meadow. "))) + MutationResult insRes = client.replace(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, txt))) .execute(); Assert.assertEquals(1, insRes.getAffectedRows()); // get - Map res = client.get(tableName, new Object[] { id }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + Map res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(null, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); // replace-conflict with non fulltext column - MutationResult updRes = client.replace(tableName).setRowKey(colVal(idCol, id)) + MutationResult updRes = client.replace(partTableName).setRowKey(colVal(idCol, id)) .addMutateRow(row(colVal(c2Col, 100))) .execute(); Assert.assertEquals(2, updRes.getAffectedRows()); // get - res = client.get(tableName, new Object[] { id }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(100, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); + // replace-conflict with fulltext column - updRes = client.replace(tableName).setRowKey(colVal(idCol, id)) - .addMutateRow(row(colVal(txtCol, " The birds chirped happily as they flew from tree to tree"))) + txt = " The birds chirped happily as they flew from tree to tree"; + updRes = client.replace(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, txt))) .execute(); Assert.assertEquals(2, updRes.getAffectedRows()); // get - res = client.get(tableName, new Object[] { id }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(100, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); // replace-conflict with all column - updRes = client.replace(tableName).setRowKey(colVal(idCol, id)) + txt = " The birds chirped happily as they flew from tree to tree"; + updRes = client.replace(partTableName).setRowKey(colVal(idCol, id)) .addMutateRow(row(colVal(c2Col, 100+id), - colVal(txtCol, " The birds chirped happily as they flew from tree to tree"))) + colVal(txtCol, txt))) .execute(); Assert.assertEquals(2, updRes.getAffectedRows()); // get - res = client.get(tableName, new Object[] { id }, null); - for (Map.Entry entry: res.entrySet()) { - System.out.println("key: "+ entry.getKey()+" value: "+ entry.getValue()); - } + res = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(100+id, res.get(c2Col)); + Assert.assertEquals(txt, res.get(txtCol)); } catch (Exception e) { e.printStackTrace(); } finally { - executeSQL(truncateTableSQL); + executeSQL(truncatePartTableSQL); } } @@ -269,37 +312,42 @@ public void testTTLInsert() throws Exception { try { // 写入新行 int id = 8; + String txt1 = "The sun rose over the horizon, casting a warm glow across the meadow. "; Timestamp curTs = new Timestamp(System.currentTimeMillis()); Timestamp expireTs = new Timestamp(System.currentTimeMillis() - 1000000); - MutationResult insRes = client.insert(ttlTableName).setRowKey(colVal(idCol, id + 1)) + MutationResult insRes = client.insert(ttlTableName).setRowKey(colVal(idCol, id)) .addMutateRow(row(colVal(expireTsCol, expireTs), - colVal(txtCol, "The sun rose over the horizon, casting a warm glow across the meadow. "))) + colVal(txtCol, txt1))) .execute(); Assert.assertEquals(1, insRes.getAffectedRows()); - insRes = client.insert(ttlTableName).setRowKey(colVal(idCol, id + 2)) + String txt2 = "The birds chirped happily as they flew from tree to tree"; + insRes = client.insert(ttlTableName).setRowKey(colVal(idCol, id + 1)) .addMutateRow(row(colVal(expireTsCol, curTs), - colVal(txtCol, "The birds chirped happily as they flew from tree to tree"))) + colVal(txtCol, txt2))) .execute(); Assert.assertEquals(1, insRes.getAffectedRows()); // 过期,删除旧行,写入新行 - insRes = client.insert(ttlTableName).setRowKey(colVal(idCol, id + 1)) + String txt3 = "Two roads diverged in a wood"; + insRes = client.insert(ttlTableName).setRowKey(colVal(idCol, id)) .addMutateRow(row(colVal(expireTsCol, curTs), - colVal(txtCol, "Two roads diverged in a wood"))) + colVal(txtCol, txt3))) .execute(); Assert.assertEquals(1, insRes.getAffectedRows()); // get - Map res = client.get(ttlTableName, new Object[]{id + 1}, null); - for (Map.Entry entry : res.entrySet()) { - System.out.println("key: " + entry.getKey() + " value: " + entry.getValue()); - } + Map res = client.get(ttlTableName, new Object[]{id}, null); + Assert.assertEquals(4, res.size()); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(curTs, res.get(expireTsCol)); + Assert.assertEquals(null, res.get(c2Col)); + Assert.assertEquals(txt3, res.get(txtCol)); // 未过期 // - insert操作 try { - client.insert(ttlTableName).setRowKey(colVal(idCol, id + 2)) + client.insert(ttlTableName).setRowKey(colVal(idCol, id + 1)) .addMutateRow(row(colVal(expireTsCol, curTs), colVal(txtCol, "I took the one less traveled by"))) .execute(); @@ -307,17 +355,19 @@ public void testTTLInsert() throws Exception { Assert.assertEquals(ResultCodes.OB_ERR_PRIMARY_KEY_DUPLICATE.errorCode, e.getErrorCode()); } // - insertup操作 - insRes = client.insertOrUpdate(ttlTableName).setRowKey(colVal(idCol, id + 2)) + String txt4 = "I took the one less traveled by"; + insRes = client.insertOrUpdate(ttlTableName).setRowKey(colVal(idCol, id + 1)) .addMutateRow(row(colVal(expireTsCol, curTs), - colVal(txtCol, "I took the one less traveled by"))) + colVal(txtCol, txt4))) .execute(); Assert.assertEquals(1, insRes.getAffectedRows()); // get - res = client.get(ttlTableName, new Object[]{id + 2}, null); - for (Map.Entry entry : res.entrySet()) { - System.out.println("key: " + entry.getKey() + " value: " + entry.getValue()); - } + res = client.get(ttlTableName, new Object[]{id + 1}, null); + Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(curTs, res.get(expireTsCol)); + Assert.assertEquals(null, res.get(c2Col)); + Assert.assertEquals(txt4, res.get(txtCol)); } catch(Exception e) { e.printStackTrace(); } finally { @@ -325,36 +375,200 @@ public void testTTLInsert() throws Exception { } } + @Test + public void testIncrment() throws Exception { + try { + // increment row not exist + int id = 9; + + MutationResult res = client.increment(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(c2Col, 1))) + .execute(); + Assert.assertEquals(1, res.getAffectedRows()); + + Map getRes = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, getRes.size()); + Assert.assertEquals(id, getRes.get(idCol)); + Assert.assertEquals(1, getRes.get(c2Col)); + Assert.assertEquals(null, getRes.get(txtCol)); + + res = client.increment(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(c2Col, 1))) + .execute(); + Assert.assertEquals(1, res.getAffectedRows()); + + getRes = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, getRes.size()); + Assert.assertEquals(id, getRes.get(idCol)); + Assert.assertEquals(2, getRes.get(c2Col)); + Assert.assertEquals(null, getRes.get(txtCol)); + } catch(Exception e) { + e.printStackTrace(); + } finally { + // executeSQL(truncateTTLTableSQL); + } + } + + @Test + public void testAppend() throws Exception { + try { + // append row not exist + int id = 10; + String txt1 = "We enjoyed a peaceful walk."; + MutationResult res = client.append(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, txt1))) + .execute(); + Assert.assertEquals(1, res.getAffectedRows()); + + Map getRes = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, getRes.size()); + Assert.assertEquals(id, getRes.get(idCol)); + Assert.assertEquals(null, getRes.get(c2Col)); + Assert.assertEquals(txt1, getRes.get(txtCol)); + + String txt2 = "Can you pass me the salt, please?"; + res = client.append(partTableName).setRowKey(colVal(idCol, id)) + .addMutateRow(row(colVal(txtCol, txt2))) + .execute(); + Assert.assertEquals(1, res.getAffectedRows()); + + getRes = client.get(partTableName, new Object[] { id }, null); + Assert.assertEquals(3, getRes.size()); + Assert.assertEquals(id, getRes.get(idCol)); + Assert.assertEquals(null, getRes.get(c2Col)); + Assert.assertEquals(txt1+txt2, getRes.get(txtCol)); + } catch(Exception e) { + e.printStackTrace(); + } finally { + // executeSQL(truncateTTLTableSQL); + } + } + + private void loadData(String tableName) throws Exception { + // load data + client.insert(tableName).setRowKey(colVal(idCol, 1)) + .addMutateRow(row(colVal(c2Col, 1), colVal(txtCol, "hello world"))) + .execute(); + client.insert(tableName).setRowKey(colVal(idCol, 2)) + .addMutateRow(row(colVal(c2Col, 2), colVal(txtCol, "OceanBase Database is a native, enterprise-level distributed database developed independently by the OceanBase team"))) + .execute(); + client.insert(tableName).setRowKey(colVal(idCol, 3)) + .addMutateRow(row(colVal(c2Col, 3), colVal(txtCol, "Learn about SQL and database administration in oceanBase"))) + .execute(); + client.insert(tableName).setRowKey(colVal(idCol, 4)) + .addMutateRow(row(colVal(c2Col, 4), colVal(txtCol, "Master the art of full text searching"))) + .execute(); + } + @Test public void testFTSQuery() throws Exception { try { - client.addRowKeyElement(tableName, new String[] {"id"}); + executeSQL(truncatePartTableSQL); + client.addRowKeyElement(partTableName, new String[] {"id"}); + //load data + loadData(partTableName); + //sync query + QueryResultSet resultSet = client.query(partTableName) + .setSearchText("oceanbase") + .indexName("full_idx1_tbl1") + .execute(); + int count = 0; + while(resultSet.next()) { + count++; + Map row = resultSet.getRow(); + Assert.assertEquals(3, row.size()); + int id = (int) row.get("id"); + Assert.assertEquals(id, row.get("c2")); + Assert.assertTrue(((String)row.get("txt")).toLowerCase(Locale.ROOT).contains("oceanbase")); + } + Assert.assertTrue(2 == count); + // async query + QueryResultSet asyncResultSet = client.query(partTableName) + .indexName("full_idx1_tbl1") + .setSearchText("oceanbase") + .asyncExecute(); + count = 0; + while(asyncResultSet.next()) { + count++; + Map row = asyncResultSet.getRow(); + Assert.assertEquals(3, row.size()); + int id = (int) row.get("id"); + Assert.assertEquals(id, row.get("c2")); + Assert.assertTrue(((String)row.get("txt")).toLowerCase(Locale.ROOT).contains("oceanbase")); + } + Assert.assertTrue(2 == count); + } catch (Exception e) { + e.printStackTrace(); + } finally { + executeSQL(truncatePartTableSQL); + } + } + + private void loadDataWithTTL() throws Exception { + // load data + Timestamp curTs = new Timestamp(System.currentTimeMillis()); + Timestamp expireTs = new Timestamp(System.currentTimeMillis() - 1000000); + client.insert(ttlTableName).setRowKey(colVal(idCol, 1)) + .addMutateRow(row(colVal(c2Col, 1), + colVal(expireTsCol, curTs), + colVal(txtCol, "Hello World"))) + .execute(); + client.insert(ttlTableName).setRowKey(colVal(idCol, 2)) + .addMutateRow(row(colVal(c2Col, 2), + colVal(expireTsCol, curTs), + colVal(txtCol, "OceanBase Database is a native, enterprise-level distributed database developed independently by the OceanBase team"))) + .execute(); + client.insert(ttlTableName).setRowKey(colVal(idCol, 3)) + .addMutateRow(row(colVal(c2Col, 3), + colVal(expireTsCol, expireTs), + colVal(txtCol, "Learn about SQL and database administration in oceanBase"))) + .execute(); + client.insert(ttlTableName).setRowKey(colVal(idCol, 4)) + .addMutateRow(row(colVal(c2Col, 4), + colVal(expireTsCol, expireTs), + colVal(txtCol, "Master the art of full text searching"))) + .execute(); + } + + @Test + public void testFTSQueryWithTTL() throws Exception { + try { + executeSQL(truncateTTLTableSQL); + client.addRowKeyElement(ttlTableName, new String[]{"id"}); + //load data + loadDataWithTTL(); //sync query - QueryResultSet resultSet = client.query(tableName) + QueryResultSet resultSet = client.query(ttlTableName) .setSearchText("oceanbase") .indexName("full_idx1_tbl1") .execute(); + int count = 0; while(resultSet.next()) { + count++; Map row = resultSet.getRow(); - for (Map.Entry entry: row.entrySet()) { - System.out.println("colname: " + entry.getKey() + " \nvalue: " + entry.getValue()); - } - System.out.println(); + Assert.assertEquals(4, row.size()); + int id = (int) row.get("id"); + Assert.assertEquals(id, row.get("c2")); + Assert.assertTrue(((String)row.get("txt")).toLowerCase(Locale.ROOT).contains("oceanbase")); } + Assert.assertTrue(1 == count); + // async query - System.out.println("========async query:========="); - QueryResultSet asyncResultSet = client.query(tableName) + QueryResultSet asyncResultSet = client.query(ttlTableName) .indexName("full_idx1_tbl1") .setSearchText("oceanbase") .asyncExecute(); + count = 0; while(asyncResultSet.next()) { + count++; Map row = asyncResultSet.getRow(); - for (Map.Entry entry: row.entrySet()) { - System.out.println("colname: " + entry.getKey() + " \nvalue: " + entry.getValue()); - } - System.out.println(); + Assert.assertEquals(4, row.size()); + int id = (int) row.get("id"); + Assert.assertEquals(id, row.get("c2")); + Assert.assertTrue(((String)row.get("txt")).toLowerCase(Locale.ROOT).contains("oceanbase")); } + Assert.assertTrue(1 == count); } catch (Exception e) { e.printStackTrace(); } @@ -365,4 +579,157 @@ private void executeSQL(String createSQL) throws SQLException { Statement statement = connection.createStatement(); statement.execute(createSQL); } + + @Test + public void testQueryWithLimitOffset() throws Exception { + try { + executeSQL(truncateNoPartTableSQL); + client.addRowKeyElement(noPartTableName, new String[] {"id"}); + //load data + loadData(noPartTableName); + //sync query + QueryResultSet resultSet = client.query(noPartTableName) + .setSearchText("oceanbase") + .indexName("full_idx1_tbl1") + .limit(0,1) + .execute(); + int count = 0; + while(resultSet.next()) { + count++; + Map row = resultSet.getRow(); + Assert.assertEquals(3, row.size()); + int id = (int) row.get("id"); + Assert.assertEquals(id, row.get("c2")); + Assert.assertTrue(((String)row.get("txt")).toLowerCase(Locale.ROOT).contains("oceanbase")); + } + Assert.assertTrue(1 == count); + + // async query + QueryResultSet asyncResultSet = client.query(noPartTableName) + .indexName("full_idx1_tbl1") + .setSearchText("oceanbase") + .limit(0,1) + .asyncExecute(); + count = 0; + while(asyncResultSet.next()) { + count++; + Map row = asyncResultSet.getRow(); + Assert.assertEquals(3, row.size()); + int id = (int) row.get("id"); + Assert.assertEquals(id, row.get("c2")); + Assert.assertTrue(((String)row.get("txt")).toLowerCase(Locale.ROOT).contains("oceanbase")); + } + Assert.assertTrue(1 == count); + } catch (Exception e) { + e.printStackTrace(); + } finally { + executeSQL(truncateNoPartTableSQL); + } + } + + @Test + public void testBatch() throws Exception { + try { + executeSQL(truncatePartTableSQL); + int rowCnt = 6; + Object values[][] = {{1, 1, "Learn about SQL and database administration in oceanBase"}, {2, 2, "Can you pass me the salt, please?"}, + {3, 3, "OceanBase Database is a native, enterprise-level distributed database"}, {4, 4, "We enjoyed a peaceful walk."}, + {5, 5, "Learn about SQL and database administration in oceanBase"}, {6, 6, "Master the art of full text searching"}}; + // multi insert + { + BatchOperation insBatchOps = client.batchOperation(partTableName); + for (int i = 0; i < rowCnt; i++) { + Object[] curRow = values[i]; + Insert insert = new Insert(); + insert.setRowKey(row(colVal(idCol, curRow[0]))); + insert.addMutateRow(row(colVal(c2Col, curRow[1]), colVal(txtCol, curRow[2]))); + insBatchOps.addOperation(insert); + } + BatchOperationResult insRes = insBatchOps.execute(); + Assert.assertEquals(6, insRes.size()); + } + // multi get + { + BatchOperation getBatchOps = client.batchOperation(partTableName); + for (int i = 0; i < rowCnt; i++) { + Object[] curRow = values[i]; + TableQuery query = client.query(partTableName).setRowKey(row(colVal(idCol, curRow[0]))); + getBatchOps.addOperation(query); + } + BatchOperationResult getRes = getBatchOps.execute(); + Assert.assertEquals(6, getRes.size()); + for (int i = 0; i < rowCnt; i++) { + int idx = (int) getRes.get(i).getOperationRow().get(idCol) - 1; + Assert.assertEquals(idx + 1, (int) getRes.get(i).getOperationRow().get(c2Col)); + Assert.assertEquals(values[idx][2], getRes.get(i).getOperationRow().get(txtCol)); + } + } + // hyper operation + { + BatchOperation hyperOps = client.batchOperation(partTableName); + // insertup + InsertOrUpdate insup = new InsertOrUpdate(); + insup.setRowKey(row(colVal(idCol, values[0][0]))) + .addMutateRow(row(colVal(c2Col, (int)values[0][1] + 100), + colVal(txtCol, values[0][2] + " " + values[1][2]))); + hyperOps.addOperation(insup); + // update + Update upd = new Update(); + upd.setRowKey(row(colVal(idCol, values[1][0]))) + .addMutateRow(row(colVal(c2Col, (int)values[1][1] + 100), + colVal(txtCol, values[1][2] + " " + values[2][2]))); + hyperOps.addOperation(upd); + // replace + Replace replace = new Replace(); + replace.setRowKey(row(colVal(idCol, values[2][0]))) + .addMutateRow(row(colVal(c2Col, (int)values[2][1] + 100), + colVal(txtCol, values[2][2] + " " + values[3][2]))); + hyperOps.addOperation(replace); + + // increment + Increment increment = new Increment(); + increment.setRowKey(row(colVal(idCol, values[3][0]))) + .addMutateRow(row(colVal(c2Col, 100))); + hyperOps.addOperation(increment); + + // append + Append append = new Append(); + append.setRowKey(row(colVal(idCol, values[3][0]))) + .addMutateRow(row(colVal(txtCol," " + values[4][2]))); + hyperOps.addOperation(append); + + BatchOperationResult hyperRes = hyperOps.execute(); + Assert.assertEquals(5, hyperRes.size()); + + BatchOperation getBatchOps = client.batchOperation(partTableName); + for (int i = 0; i < rowCnt - 2; i++) { + Object[] curRow = values[i]; + TableQuery query = client.query(partTableName).setRowKey(row(colVal(idCol, curRow[0]))); + getBatchOps.addOperation(query); + } + BatchOperationResult getRes = getBatchOps.execute(); + Assert.assertEquals(4, getRes.size()); + for (int i = 0; i < rowCnt - 2; i++) { + int idx = (int) getRes.get(i).getOperationRow().get(idCol) - 1; + Assert.assertEquals((int)values[idx][1] + 100, (int) getRes.get(i).getOperationRow().get(c2Col)); + Assert.assertEquals(values[idx][2] + " " + values[idx + 1][2], getRes.get(i).getOperationRow().get(txtCol)); + } + } + // multi delete + { + BatchOperation delBatchOps = client.batchOperation(partTableName); + for (int i = 0; i < rowCnt; i++) { + Object[] curRow = values[i]; + Delete delete = new Delete(); + delete.setRowKey(row(colVal(idCol, curRow[0]))); + delBatchOps.addOperation(delete); + } + BatchOperationResult delRes = delBatchOps.setReturnOneResult(true).execute(); + Assert.assertEquals(1, delRes.size()); + Assert.assertEquals(6, delRes.get(0).getAffectedRows()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } } From 9de0ecd68a0869c91a835f641db8830def4eb207 Mon Sep 17 00:00:00 2001 From: GroundWu <1175416256@qq.com> Date: Mon, 11 Nov 2024 11:57:38 +0800 Subject: [PATCH 5/8] fix case fail --- .../com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java b/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java index e923bb1d..9527c28e 100644 --- a/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java +++ b/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java @@ -271,7 +271,7 @@ public void testReplace() throws Exception { Assert.assertEquals(3, res.size()); Assert.assertEquals(id, res.get(idCol)); Assert.assertEquals(100, res.get(c2Col)); - Assert.assertEquals(txt, res.get(txtCol)); + Assert.assertEquals(null, res.get(txtCol)); // replace-conflict with fulltext column txt = " The birds chirped happily as they flew from tree to tree"; @@ -283,7 +283,7 @@ public void testReplace() throws Exception { res = client.get(partTableName, new Object[] { id }, null); Assert.assertEquals(3, res.size()); Assert.assertEquals(id, res.get(idCol)); - Assert.assertEquals(100, res.get(c2Col)); + Assert.assertEquals(null, res.get(c2Col)); Assert.assertEquals(txt, res.get(txtCol)); // replace-conflict with all column @@ -364,7 +364,7 @@ public void testTTLInsert() throws Exception { // get res = client.get(ttlTableName, new Object[]{id + 1}, null); - Assert.assertEquals(id, res.get(idCol)); + Assert.assertEquals(id + 1, res.get(idCol)); Assert.assertEquals(curTs, res.get(expireTsCol)); Assert.assertEquals(null, res.get(c2Col)); Assert.assertEquals(txt4, res.get(txtCol)); From bfa9947aa3ad09735ac346d6bdbedfc645ec57fc Mon Sep 17 00:00:00 2001 From: GroundWu <1175416256@qq.com> Date: Thu, 28 Nov 2024 21:22:44 +0800 Subject: [PATCH 6/8] fix fts query bugs --- .../rpc/stream/ObTableClientQueryAsyncStreamResult.java | 4 ++-- .../alipay/oceanbase/rpc/table/ObTableClientQueryImpl.java | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/alipay/oceanbase/rpc/stream/ObTableClientQueryAsyncStreamResult.java b/src/main/java/com/alipay/oceanbase/rpc/stream/ObTableClientQueryAsyncStreamResult.java index 5ee9c3bd..e4256677 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/stream/ObTableClientQueryAsyncStreamResult.java +++ b/src/main/java/com/alipay/oceanbase/rpc/stream/ObTableClientQueryAsyncStreamResult.java @@ -119,9 +119,9 @@ protected ObTableQueryAsyncResult referToNewPartition(ObPair queryRequest.setPartitionId(obTableParam.getPartitionId()); queryRequest.setTableId(obTableParam.getTableId()); if (operationTimeout > 0) { - queryRequest.setTimeout(operationTimeout); + asyncRequest.setTimeout(operationTimeout); } else { - queryRequest.setTimeout(obTableParam.getObTable().getObTableOperationTimeout()); + asyncRequest.setTimeout(obTableParam.getObTable().getObTableOperationTimeout()); } // refresh async query request diff --git a/src/main/java/com/alipay/oceanbase/rpc/table/ObTableClientQueryImpl.java b/src/main/java/com/alipay/oceanbase/rpc/table/ObTableClientQueryImpl.java index 6d42cdaf..46b2ea3a 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/table/ObTableClientQueryImpl.java +++ b/src/main/java/com/alipay/oceanbase/rpc/table/ObTableClientQueryImpl.java @@ -164,6 +164,11 @@ private AbstractQueryStreamResult commonExecute(InitQueryResultCallback Date: Fri, 29 Nov 2024 15:47:44 +0800 Subject: [PATCH 7/8] opt case --- .../rpc/ObTableFullTextIndexTest.java | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java b/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java index 9527c28e..9884f1d9 100644 --- a/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java +++ b/src/test/java/com/alipay/oceanbase/rpc/ObTableFullTextIndexTest.java @@ -40,7 +40,6 @@ public class ObTableFullTextIndexTest { String truncateNoPartTableSQL = "truncate table tbl1;"; String truncatePartTableSQL = "truncate table part_tbl1;"; String truncateTTLTableSQL = "truncate table ttl_tbl1;"; - String dropTableSQL = "drop table tbl1"; String idCol = "id"; String c2Col = "c2"; String txtCol = "txt"; @@ -57,7 +56,9 @@ public void setup() throws Exception { @After public void teardown() throws Exception { -// executeSQL(dropTableSQL); + executeSQL("drop table " + noPartTableName); + executeSQL("drop table " + partTableName); + executeSQL("drop table " + ttlTableName); } @Test @@ -71,6 +72,9 @@ public void testInsert() throws Exception { Assert.assertEquals(1, res.getAffectedRows()); } catch (Exception e) { e.printStackTrace(); + Assert.fail(); + } finally { + executeSQL(truncatePartTableSQL); } } @@ -92,6 +96,9 @@ public void testGet() throws Exception { Assert.assertEquals(txt, res.get(txtCol)); } catch (Exception e) { e.printStackTrace(); + Assert.fail(); + } finally { + executeSQL(truncatePartTableSQL); } } @@ -119,6 +126,9 @@ public void testDel() throws Exception { Assert.assertTrue(res.isEmpty()); } catch (Exception e) { e.printStackTrace(); + Assert.fail(); + } finally { + executeSQL(truncatePartTableSQL); } } @@ -178,6 +188,9 @@ public void testUpd() throws Exception { Assert.assertEquals(txt, res.get(txtCol)); } catch (Exception e) { e.printStackTrace(); + Assert.fail(); + } finally { + executeSQL(truncatePartTableSQL); } } @@ -239,6 +252,7 @@ public void testInsOrUpd() throws Exception { } catch (Exception e) { e.printStackTrace(); + Assert.fail(); } finally { executeSQL(truncatePartTableSQL); } @@ -302,6 +316,7 @@ public void testReplace() throws Exception { } catch (Exception e) { e.printStackTrace(); + Assert.fail(); } finally { executeSQL(truncatePartTableSQL); } @@ -370,8 +385,9 @@ public void testTTLInsert() throws Exception { Assert.assertEquals(txt4, res.get(txtCol)); } catch(Exception e) { e.printStackTrace(); + Assert.fail(); } finally { - // executeSQL(truncateTTLTableSQL); + executeSQL(truncateTTLTableSQL); } } @@ -404,8 +420,9 @@ public void testIncrment() throws Exception { Assert.assertEquals(null, getRes.get(txtCol)); } catch(Exception e) { e.printStackTrace(); + Assert.fail(); } finally { - // executeSQL(truncateTTLTableSQL); + executeSQL(truncatePartTableSQL); } } @@ -439,8 +456,9 @@ public void testAppend() throws Exception { Assert.assertEquals(txt1+txt2, getRes.get(txtCol)); } catch(Exception e) { e.printStackTrace(); + Assert.fail(); } finally { - // executeSQL(truncateTTLTableSQL); + executeSQL(truncatePartTableSQL); } } @@ -500,6 +518,7 @@ public void testFTSQuery() throws Exception { Assert.assertTrue(2 == count); } catch (Exception e) { e.printStackTrace(); + Assert.fail(); } finally { executeSQL(truncatePartTableSQL); } @@ -571,6 +590,9 @@ public void testFTSQueryWithTTL() throws Exception { Assert.assertTrue(1 == count); } catch (Exception e) { e.printStackTrace(); + Assert.fail(); + } finally { + executeSQL(truncateTTLTableSQL); } } @@ -622,6 +644,7 @@ public void testQueryWithLimitOffset() throws Exception { Assert.assertTrue(1 == count); } catch (Exception e) { e.printStackTrace(); + Assert.fail(); } finally { executeSQL(truncateNoPartTableSQL); } @@ -730,6 +753,9 @@ public void testBatch() throws Exception { } } catch (Exception e) { e.printStackTrace(); + Assert.fail(); + } finally { + executeSQL(truncatePartTableSQL); } } } From 79c4b765fbe9fae151e92868a2bb6f93a4d0b280 Mon Sep 17 00:00:00 2001 From: GroundWu <1175416256@qq.com> Date: Fri, 29 Nov 2024 17:23:29 +0800 Subject: [PATCH 8/8] fix fts query is always true --- .../rpc/protocol/payload/impl/execute/query/ObTableQuery.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java index b0acfb6d..204b0798 100644 --- a/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java +++ b/src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/execute/query/ObTableQuery.java @@ -69,7 +69,7 @@ public class ObTableQuery extends AbstractPayload { private static final byte[] HTABLE_DUMMY_BYTES = new byte[] { 0x01, 0x00 }; private boolean isHbaseQuery = false; - private boolean isFTSQuery = true; + private boolean isFTSQuery = false; private List scanRangeColumns = new LinkedList(); private List aggregations = new LinkedList<>();