diff --git a/pkg/vm/engine/tae/common/compare.go b/pkg/vm/engine/tae/common/compare.go
index 0d428f06b354da24843cb334dc82cc7f23cdea96..59a9f7bddd9fbfeb7ba62dc62bb65c8591ee2d85 100644
--- a/pkg/vm/engine/tae/common/compare.go
+++ b/pkg/vm/engine/tae/common/compare.go
@@ -106,6 +106,14 @@ func CompareGeneric(a, b any, t types.Type) int {
 		} else {
 			return 0
 		}
+	case types.T_timestamp:
+		if a.(types.Timestamp) > b.(types.Timestamp) {
+			return 1
+		} else if a.(types.Timestamp) < b.(types.Timestamp) {
+			return -1
+		} else {
+			return 0
+		}
 	case types.T_date:
 		if a.(types.Date) > b.(types.Date) {
 			return 1
diff --git a/pkg/vm/engine/tae/container/compute/compute.go b/pkg/vm/engine/tae/container/compute/compute.go
index 65177cef3a764e5f99eaaba67b336e8475984f06..bd1d9f16fbf2605292ec9b591a15778d5708d3a8 100644
--- a/pkg/vm/engine/tae/container/compute/compute.go
+++ b/pkg/vm/engine/tae/container/compute/compute.go
@@ -71,6 +71,9 @@ func AppendValue(vec *gvec.Vector, v any) {
 	case types.T_date:
 		vvals := vec.Col.([]types.Date)
 		vec.Col = append(vvals, v.(types.Date))
+	case types.T_timestamp:
+		vvals := vec.Col.([]types.Timestamp)
+		vec.Col = append(vvals, v.(types.Timestamp))
 	case types.T_datetime:
 		vvals := vec.Col.([]types.Datetime)
 		vec.Col = append(vvals, v.(types.Datetime))
diff --git a/pkg/vm/engine/tae/container/compute/utils.go b/pkg/vm/engine/tae/container/compute/utils.go
index 7b2c03fed040fcde4786f38cb69ace9324b8ad23..b758f7a7001ad640e36fc3d4d0ef75a7e99cd682 100644
--- a/pkg/vm/engine/tae/container/compute/utils.go
+++ b/pkg/vm/engine/tae/container/compute/utils.go
@@ -136,6 +136,8 @@ func EncodeKey(key any, typ types.Type) ([]byte, error) {
 		} else {
 			panic("unsupported type")
 		}
+	case types.T_timestamp:
+		return encoding.EncodeTimestamp(key.(types.Timestamp)), nil
 	case types.T_datetime:
 		if v, ok := key.(types.Datetime); ok {
 			return encoding.EncodeDatetime(v), nil
@@ -351,6 +353,22 @@ func ProcessVector(vec *vector.Vector, offset uint32, length uint32, task func(v
 				}
 			}
 		}
+	case types.T_timestamp:
+		vs := vec.Col.([]types.Timestamp)[offset:]
+		if keyselects == nil {
+			for i, v := range vs {
+				if err := task(v, uint32(i)); err != nil {
+					return err
+				}
+			}
+		} else {
+			for _, idx := range idxes {
+				v := vs[idx]
+				if err := task(v, idx); err != nil {
+					return err
+				}
+			}
+		}
 	case types.T_date:
 		vs := vec.Col.([]types.Date)[offset:]
 		if keyselects == nil {
diff --git a/pkg/vm/engine/tae/txn/txnimpl/index.go b/pkg/vm/engine/tae/txn/txnimpl/index.go
index 1ec34d0149d65c66772ce23d17451c735909864c..533d3ba52536e21b6fd8f2cd40c9d402d7e84cab 100644
--- a/pkg/vm/engine/tae/txn/txnimpl/index.go
+++ b/pkg/vm/engine/tae/txn/txnimpl/index.go
@@ -349,6 +349,25 @@ func (idx *simpleTableIndex) BatchInsert(col *gvec.Vector, start, count int, row
 			idx.tree[v] = row
 			row++
 		}
+	case types.T_timestamp:
+		data := vals.([]types.Timestamp)
+		if dedupCol {
+			set := make(map[types.Timestamp]bool)
+			for _, v := range data[start : start+count] {
+				if _, ok := set[v]; ok {
+					return idata.ErrDuplicate
+				}
+				set[v] = true
+			}
+			break
+		}
+		for _, v := range data[start : start+count] {
+			if _, ok := idx.tree[v]; ok {
+				return idata.ErrDuplicate
+			}
+			idx.tree[v] = row
+			row++
+		}
 	case types.T_datetime:
 		data := vals.([]types.Datetime)
 		if dedupCol {