diff --git a/cgo/Makefile b/cgo/Makefile
index 727539f49ad47c4ab0440081ab7713f45868e682..941fd63541f152c8ac3fd3fca4db2ea934b082d0 100644
--- a/cgo/Makefile
+++ b/cgo/Makefile
@@ -1,7 +1,7 @@
 DEBUG_OPT :=
 OPT_LV := -O3
 CFLAGS=-I./external/decNumber -g ${OPT_LV} -Wall -Werror
-OBJS=mo.o arith.o decimal.o
+OBJS=mo.o arith.o compare.o decimal.o
 
 all: libmo.a
 
diff --git a/cgo/arith.c b/cgo/arith.c
index ade03639f0990d9bca65856b7df71237e6d186a3..f1d69ca4a0a031eb64523bcf9766276cf11ab3a3 100644
--- a/cgo/arith.c
+++ b/cgo/arith.c
@@ -15,7 +15,6 @@
  */
 
 #include "mo_impl.h"
-#include <math.h>
 
 /* 
  * Signed int add with overflow check.
@@ -219,10 +218,6 @@
         return RC_DIVISION_BY_ZERO;                 \
     } else return RC_SUCCESS
 
-
-const int32_t LEFT_IS_SCALAR = 1;
-const int32_t RIGHT_IS_SCALAR = 2;
-
 // MO_ARITH_T: Handle general arithmetic operations
 #define MO_ARITH_T(OP, ZT)                                    \
     ZT *rt = (ZT *) r;                                        \
diff --git a/cgo/compare.c b/cgo/compare.c
new file mode 100644
index 0000000000000000000000000000000000000000..07a076b38f2cd5b280991668f99b3b874af89b84
--- /dev/null
+++ b/cgo/compare.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2021 Matrix Origin
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mo_impl.h"
+
+
+#define	Type_BOOL     10
+#define	Type_INT8     20
+#define	Type_INT16    21
+#define	Type_INT32    22
+#define	Type_INT64    23
+#define	Type_INT128   24
+#define	Type_UINT8    25
+#define	Type_UINT16   26
+#define	Type_UINT32   27
+#define	Type_UINT64   28
+#define	Type_UINT128  29
+#define	Type_FLOAT32  30
+#define	Type_FLOAT64  31
+
+// Time
+#define Type_DATE       50
+#define Type_DATETIME   52
+#define Type_TIMESTAMP  53
+
+
+/*
+ * Equal operator (=)
+ */
+#define COMPARE_EQ(TGT, A, B)                                 \
+    TGT = ((A) == (B))
+
+
+/*
+ * Not Equal operator (<>)
+ */
+#define COMPARE_NE(TGT, A, B)                                 \
+    TGT = ((A) != (B))
+
+
+/*
+ * great than operator (>)
+ */
+#define COMPARE_GT(TGT, A, B)                                 \
+    TGT = ((A) > (B))
+
+
+/*
+ * great equal operator (>=)
+ */
+#define COMPARE_GE(TGT, A, B)                                 \
+    TGT = ((A) >= (B))
+
+
+/*
+ * less than operator (<)
+ */
+#define COMPARE_LT(TGT, A, B)                                 \
+    TGT = ((A) < (B))
+
+
+/*
+ * less equal operator (<=)
+ */
+#define COMPARE_LE(TGT, A, B)                                 \
+    TGT = ((A) <= (B))
+
+
+/*
+ * bool compare operator
+ */
+#define COMPARE_BOOL_EQ(TGT, A, B)                                     \
+    TGT = (((A) && (B)) || (!(A) && !(B)))
+
+#define COMPARE_BOOL_NE(TGT, A, B)                                     \
+    TGT = ((!(A) && (B)) || ((A) && !(B)))
+
+#define COMPARE_BOOL_LE(TGT, A, B)                                     \
+    TGT = (!(A) || (B))
+
+#define COMPARE_BOOL_LT(TGT, A, B)                                     \
+    TGT = (!(A) && (B))
+
+#define COMPARE_BOOL_GE(TGT, A, B)                                     \
+    TGT = ((A) || !(B))
+
+#define COMPARE_BOOL_GT(TGT, A, B)                                     \
+    TGT = ((A) && !(B))
+
+
+
+
+
+#define MO_COMPARE_T(OP, ZT)                                  \
+    bool *rt = (bool *) r;                                    \
+    ZT *at = (ZT *) a;                                        \
+    ZT *bt = (ZT *) b;                                        \
+    if ((flag & LEFT_IS_SCALAR) != 0) {                       \
+        if (nulls != NULL) {                                  \
+            for (uint64_t i = 0; i < n; i++) {                \
+                if (!bitmap_test(nulls, i)) {                 \
+                    OP(rt[i], at[0], bt[i]);                  \
+                }                                             \
+            }                                                 \
+        } else {                                              \
+            for (uint64_t i = 0; i < n; i++) {                \
+                OP(rt[i], at[0], bt[i]);                      \
+            }                                                 \
+        }                                                     \
+    } else if ((flag & RIGHT_IS_SCALAR) != 0) {               \
+        if (nulls != NULL) {                                  \
+            for (uint64_t i = 0; i < n; i++) {                \
+                if (!bitmap_test(nulls, i)) {                 \
+                    OP(rt[i], at[i], bt[0]);                  \
+                }                                             \
+            }                                                 \
+        } else {                                              \
+            for (uint64_t i = 0; i < n; i++) {                \
+                OP(rt[i], at[i], bt[0]);                      \
+            }                                                 \
+        }                                                     \
+    } else {                                                  \
+        if (nulls != NULL) {                                  \
+            for (uint64_t i = 0; i < n; i++) {                \
+                if (!bitmap_test(nulls, i)) {                 \
+                    OP(rt[i], at[i], bt[i]);                  \
+                }                                             \
+            }                                                 \
+        } else {                                              \
+            for (uint64_t i = 0; i < n; i++) {                \
+                OP(rt[i], at[i], bt[i]);                      \
+            }                                                 \
+        }                                                     \
+    }
+
+
+
+int32_t Numeric_VecEq(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type)
+{
+    if (type == Type_INT8) {
+        MO_COMPARE_T(COMPARE_EQ, int8_t);
+    } else if (type == Type_INT16) {
+        MO_COMPARE_T(COMPARE_EQ, int16_t);
+    } else if (type == Type_INT32) {
+        MO_COMPARE_T(COMPARE_EQ, int32_t);
+    } else if (type == Type_INT64) {
+        MO_COMPARE_T(COMPARE_EQ, int64_t);
+    } else if (type == Type_UINT8) {
+        MO_COMPARE_T(COMPARE_EQ, uint8_t);
+    } else if (type == Type_UINT16) {
+        MO_COMPARE_T(COMPARE_EQ, uint16_t);
+    } else if (type == Type_UINT32) {
+        MO_COMPARE_T(COMPARE_EQ, uint32_t);
+    } else if (type == Type_UINT64) {
+        MO_COMPARE_T(COMPARE_EQ, uint64_t);
+    } else if (type == Type_FLOAT32) {
+        MO_COMPARE_T(COMPARE_EQ, float);
+    } else if (type == Type_FLOAT64) {
+        MO_COMPARE_T(COMPARE_EQ, double);
+    } else if (type == Type_DATE) {
+        MO_COMPARE_T(COMPARE_EQ, int32_t);
+    } else if (type == Type_DATETIME) {
+        MO_COMPARE_T(COMPARE_EQ, int64_t);
+    } else if (type == Type_TIMESTAMP) {
+        MO_COMPARE_T(COMPARE_EQ, int64_t);
+    } else if (type == Type_BOOL) {
+        MO_COMPARE_T(COMPARE_BOOL_EQ, bool);
+    } else {
+        return RC_INVALID_ARGUMENT;
+    }
+    return RC_SUCCESS;
+}
+
+
+int32_t Numeric_VecNe(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type)
+{
+    if (type == Type_INT8) {
+        MO_COMPARE_T(COMPARE_NE, int8_t);
+    } else if (type == Type_INT16) {
+        MO_COMPARE_T(COMPARE_NE, int16_t);
+    } else if (type == Type_INT32) {
+        MO_COMPARE_T(COMPARE_NE, int32_t);
+    } else if (type == Type_INT64) {
+        MO_COMPARE_T(COMPARE_NE, int64_t);
+    } else if (type == Type_UINT8) {
+        MO_COMPARE_T(COMPARE_NE, uint8_t);
+    } else if (type == Type_UINT16) {
+        MO_COMPARE_T(COMPARE_NE, uint16_t);
+    } else if (type == Type_UINT32) {
+        MO_COMPARE_T(COMPARE_NE, uint32_t);
+    } else if (type == Type_UINT64) {
+        MO_COMPARE_T(COMPARE_NE, uint64_t);
+    } else if (type == Type_FLOAT32) {
+        MO_COMPARE_T(COMPARE_NE, float);
+    } else if (type == Type_FLOAT64) {
+        MO_COMPARE_T(COMPARE_NE, double);
+    } else if (type == Type_DATE) {
+        MO_COMPARE_T(COMPARE_NE, int32_t);
+    } else if (type == Type_DATETIME) {
+        MO_COMPARE_T(COMPARE_NE, int64_t);
+    } else if (type == Type_TIMESTAMP) {
+        MO_COMPARE_T(COMPARE_NE, int64_t);
+    } else if (type == Type_BOOL) {
+        MO_COMPARE_T(COMPARE_BOOL_NE, bool);
+    } else {
+        return RC_INVALID_ARGUMENT;
+    }
+    return RC_SUCCESS;
+}
+
+
+int32_t Numeric_VecGt(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type)
+{
+    if (type == Type_INT8) {
+        MO_COMPARE_T(COMPARE_GT, int8_t);
+    } else if (type == Type_INT16) {
+        MO_COMPARE_T(COMPARE_GT, int16_t);
+    } else if (type == Type_INT32) {
+        MO_COMPARE_T(COMPARE_GT, int32_t);
+    } else if (type == Type_INT64) {
+        MO_COMPARE_T(COMPARE_GT, int64_t);
+    } else if (type == Type_UINT8) {
+        MO_COMPARE_T(COMPARE_GT, uint8_t);
+    } else if (type == Type_UINT16) {
+        MO_COMPARE_T(COMPARE_GT, uint16_t);
+    } else if (type == Type_UINT32) {
+        MO_COMPARE_T(COMPARE_GT, uint32_t);
+    } else if (type == Type_UINT64) {
+        MO_COMPARE_T(COMPARE_GT, uint64_t);
+    } else if (type == Type_FLOAT32) {
+        MO_COMPARE_T(COMPARE_GT, float);
+    } else if (type == Type_FLOAT64) {
+        MO_COMPARE_T(COMPARE_GT, double);
+    } else if (type == Type_DATE) {
+        MO_COMPARE_T(COMPARE_GT, int32_t);
+    } else if (type == Type_DATETIME) {
+        MO_COMPARE_T(COMPARE_GT, int64_t);
+    } else if (type == Type_TIMESTAMP) {
+        MO_COMPARE_T(COMPARE_GT, int64_t);
+    } else if (type == Type_BOOL) {
+        MO_COMPARE_T(COMPARE_BOOL_GT, bool);
+    } else {
+        return RC_INVALID_ARGUMENT;
+    }
+    return RC_SUCCESS;
+}
+
+int32_t Numeric_VecGe(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type)
+{
+    if (type == Type_INT8) {
+        MO_COMPARE_T(COMPARE_GE, int8_t);
+    } else if (type == Type_INT16) {
+        MO_COMPARE_T(COMPARE_GE, int16_t);
+    } else if (type == Type_INT32) {
+        MO_COMPARE_T(COMPARE_GE, int32_t);
+    } else if (type == Type_INT64) {
+        MO_COMPARE_T(COMPARE_GE, int64_t);
+    } else if (type == Type_UINT8) {
+        MO_COMPARE_T(COMPARE_GE, uint8_t);
+    } else if (type == Type_UINT16) {
+        MO_COMPARE_T(COMPARE_GE, uint16_t);
+    } else if (type == Type_UINT32) {
+        MO_COMPARE_T(COMPARE_GE, uint32_t);
+    } else if (type == Type_UINT64) {
+        MO_COMPARE_T(COMPARE_GE, uint64_t);
+    } else if (type == Type_FLOAT32) {
+        MO_COMPARE_T(COMPARE_GE, float);
+    } else if (type == Type_FLOAT64) {
+        MO_COMPARE_T(COMPARE_GE, double);
+    } else if (type == Type_DATE) {
+        MO_COMPARE_T(COMPARE_GE, int32_t);
+    } else if (type == Type_DATETIME) {
+        MO_COMPARE_T(COMPARE_GE, int64_t);
+    } else if (type == Type_TIMESTAMP) {
+        MO_COMPARE_T(COMPARE_GE, int64_t);
+    } else if (type == Type_BOOL) {
+        MO_COMPARE_T(COMPARE_BOOL_GE, bool);
+    } else {
+        return RC_INVALID_ARGUMENT;
+    }
+
+    return RC_SUCCESS;
+}
+
+
+int32_t Numeric_VecLt(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type)
+{
+    if (type == Type_INT8) {
+        MO_COMPARE_T(COMPARE_LT, int8_t);
+    } else if (type == Type_INT16) {
+        MO_COMPARE_T(COMPARE_LT, int16_t);
+    } else if (type == Type_INT32) {
+        MO_COMPARE_T(COMPARE_LT, int32_t);
+    } else if (type == Type_INT64) {
+        MO_COMPARE_T(COMPARE_LT, int64_t);
+    } else if (type == Type_UINT8) {
+        MO_COMPARE_T(COMPARE_LT, uint8_t);
+    } else if (type == Type_UINT16) {
+        MO_COMPARE_T(COMPARE_LT, uint16_t);
+    } else if (type == Type_UINT32) {
+        MO_COMPARE_T(COMPARE_LT, uint32_t);
+    } else if (type == Type_UINT64) {
+        MO_COMPARE_T(COMPARE_LT, uint64_t);
+    } else if (type == Type_FLOAT32) {
+        MO_COMPARE_T(COMPARE_LT, float);
+    } else if (type == Type_FLOAT64) {
+        MO_COMPARE_T(COMPARE_LT, double);
+    } else if (type == Type_DATE) {
+        MO_COMPARE_T(COMPARE_LT, int32_t);
+    } else if (type == Type_DATETIME) {
+        MO_COMPARE_T(COMPARE_LT, int64_t);
+    } else if (type == Type_TIMESTAMP) {
+        MO_COMPARE_T(COMPARE_LT, int64_t);
+    } else if (type == Type_BOOL) {
+        MO_COMPARE_T(COMPARE_BOOL_LT, bool);
+    } else {
+        return RC_INVALID_ARGUMENT;
+    }
+    return RC_SUCCESS;
+}
+
+
+int32_t Numeric_VecLe(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type)
+{
+    if (type == Type_INT8) {
+        MO_COMPARE_T(COMPARE_LE, int8_t);
+    } else if (type == Type_INT16) {
+        MO_COMPARE_T(COMPARE_LE, int16_t);
+    } else if (type == Type_INT32) {
+        MO_COMPARE_T(COMPARE_LE, int32_t);
+    } else if (type == Type_INT64) {
+        MO_COMPARE_T(COMPARE_LE, int64_t);
+    } else if (type == Type_UINT8) {
+        MO_COMPARE_T(COMPARE_LE, uint8_t);
+    } else if (type == Type_UINT16) {
+        MO_COMPARE_T(COMPARE_LE, uint16_t);
+    } else if (type == Type_UINT32) {
+        MO_COMPARE_T(COMPARE_LE, uint32_t);
+    } else if (type == Type_UINT64) {
+        MO_COMPARE_T(COMPARE_LE, uint64_t);
+    } else if (type == Type_FLOAT32) {
+        MO_COMPARE_T(COMPARE_LE, float);
+    } else if (type == Type_FLOAT64) {
+        MO_COMPARE_T(COMPARE_LE, double);
+    } else if (type == Type_DATE) {
+        MO_COMPARE_T(COMPARE_LE, int32_t);
+    } else if (type == Type_DATETIME) {
+        MO_COMPARE_T(COMPARE_LE, int64_t);
+    } else if (type == Type_TIMESTAMP) {
+        MO_COMPARE_T(COMPARE_LE, int64_t);
+    } else if (type == Type_BOOL) {
+        MO_COMPARE_T(COMPARE_BOOL_LE, bool);
+    } else {
+        return RC_INVALID_ARGUMENT;
+    }
+    return RC_SUCCESS;
+}
\ No newline at end of file
diff --git a/cgo/decimal.c b/cgo/decimal.c
index f3fb5f4f16d04fee65615b405a86596a032f0af3..7f47847bd535981ba74e9f0f53de94bb3c0526b3 100644
--- a/cgo/decimal.c
+++ b/cgo/decimal.c
@@ -1131,4 +1131,145 @@ int32_t Decimal128_VecDiv(int64_t *r, int64_t *a, int64_t *b, uint64_t n, uint64
         }
         return RC_SUCCESS;
     }
-}
\ No newline at end of file
+}
+
+
+// Comparison operation series
+
+#define  EQ     // =   EQUAL
+#define  NE     // <>  NOT_EQUAL
+#define  GT     // >   GREAT_THAN
+#define  GE     // >=  GREAT_EQUAL
+#define  LT     // <   LESS_THAN
+#define  LE     // <=  LESS_EQUAL
+
+// EQUAL
+#define DEC_COMP_EQ(TGT, R)                                           \
+    TGT = (R == 0)
+
+// NOT EQUAL
+#define DEC_COMP_NE(TGT, R)                                           \
+    TGT = (R != 0)
+
+// GREAT_THAN
+#define DEC_COMP_GT(TGT, R)                                           \
+    TGT = (R == 1)
+
+// GREAT_EQUAL
+#define DEC_COMP_GE(TGT, R)                                           \
+    TGT = (R != -1)
+
+// LESS_THAN
+#define DEC_COMP_LT(TGT, R)                                           \
+    TGT = (R == -1)
+
+// LESS_EQUAL
+#define DEC_COMP_LE(TGT, R)                                           \
+    TGT = (R != 1)
+
+
+#define DEF_DECIMAL_COMPARE(NBITS, NAME ,OP)                          \
+int32_t Decimal ## NBITS ## _Vec ## NAME(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag) { \
+    int32_t cmp = 0;                                                  \
+    if ((flag & 1) != 0) {                                            \
+        if (nulls != NULL) {                                          \
+            for (uint64_t i = 0; i < n; i++) {                        \
+                uint64_t ii = i << (NBITS / 64 - 1);                  \
+                if (!bitmap_test(nulls, i)) {                         \
+                    int ret = Decimal ## NBITS ## _Compare (&cmp, a, b+ii); \
+                    OP(r[i], cmp);                                    \
+                    if (ret != RC_SUCCESS) {                          \
+                        return ret;                                   \
+                    }                                                 \
+                }                                                     \
+            }                                                         \
+        } else {                                                      \
+            for (uint64_t i = 0; i < n; i++) {                        \
+                uint64_t ii = i << (NBITS / 64 - 1);                  \
+                int ret = Decimal ## NBITS ## _Compare (&cmp, a, b+ii);\
+                OP(r[i], cmp);                                        \
+                if (ret != RC_SUCCESS) {                              \
+                    return ret;                                       \
+                }                                                     \
+            }                                                         \
+        }                                                             \
+        return RC_SUCCESS;                                            \
+    } else if ((flag & 2) != 0) {                                     \
+        if (nulls != NULL) {                                          \
+            for (uint64_t i = 0; i < n; i++) {                        \
+                uint64_t ii = i << (NBITS / 64 - 1);                  \
+                if (!bitmap_test(nulls, i)) {                         \
+                    int ret = Decimal ## NBITS ## _Compare (&cmp, a+ii, b); \
+                    OP(r[i], cmp);                                    \
+                    if (ret != RC_SUCCESS) {                          \
+                        return ret;                                   \
+                    }                                                 \
+                }                                                     \
+            }                                                         \
+        } else {                                                      \
+            for (uint64_t i = 0; i < n; i++) {                        \
+                uint64_t ii = i << (NBITS / 64 - 1);                  \
+                int ret = Decimal ## NBITS ## _Compare (&cmp, a+ii, b);\
+                OP(r[i], cmp);                                        \
+                if (ret != RC_SUCCESS) {                              \
+                    return ret;                                       \
+                }                                                     \
+            }                                                         \
+        }                                                             \
+        return RC_SUCCESS;                                            \
+    } else {                                                          \
+        if (nulls != NULL) {                                          \
+            for (uint64_t i = 0; i < n; i++) {                        \
+                uint64_t ii = i << (NBITS / 64 - 1);                  \
+                if (!bitmap_test(nulls, i)) {                         \
+                    int ret = Decimal ## NBITS ## _Compare (&cmp, a+ii, b+ii); \
+                    OP(r[i], cmp);                                    \
+                    if (ret != RC_SUCCESS) {                          \
+                        return ret;                                   \
+                    }                                                 \
+                }                                                     \
+            }                                                         \
+        } else {                                                      \
+            for (uint64_t i = 0; i < n; i++) {                        \
+                uint64_t ii = i << (NBITS / 64 - 1);                  \
+                int ret = Decimal ## NBITS ## _Compare (&cmp, a+ii, b+ii); \
+                OP(r[i], cmp);                                        \
+                if (ret != RC_SUCCESS) {                              \
+                    return ret;                                       \
+                }                                                     \
+            }                                                         \
+        }                                                             \
+        return RC_SUCCESS;                                            \
+    }                                                                 \
+}
+
+
+// equal (=)
+DEF_DECIMAL_COMPARE(64, EQ, DEC_COMP_EQ)
+
+DEF_DECIMAL_COMPARE(128, EQ, DEC_COMP_EQ)
+
+// not equal (<>)
+DEF_DECIMAL_COMPARE(64, NE, DEC_COMP_NE)
+
+DEF_DECIMAL_COMPARE(128, NE, DEC_COMP_NE)
+
+// great than (>)
+DEF_DECIMAL_COMPARE(64, GT, DEC_COMP_GT)
+
+DEF_DECIMAL_COMPARE(128, GT, DEC_COMP_GT)
+
+// great equal (>=)
+DEF_DECIMAL_COMPARE(64, GE, DEC_COMP_GE)
+
+DEF_DECIMAL_COMPARE(128, GE, DEC_COMP_GE)
+
+// less than (<)
+DEF_DECIMAL_COMPARE(64, LT, DEC_COMP_LT)
+
+DEF_DECIMAL_COMPARE(128, LT, DEC_COMP_LT)
+
+// less equal (<=)
+DEF_DECIMAL_COMPARE(64, LE, DEC_COMP_LE)
+
+DEF_DECIMAL_COMPARE(128, LE, DEC_COMP_LE)
\ No newline at end of file
diff --git a/cgo/mo.h b/cgo/mo.h
index b42118e37cf15965efc0c68ede61bf1dc40345ed..8cd3038f2c83d6305ceb40bf63050ae3c39964cd 100644
--- a/cgo/mo.h
+++ b/cgo/mo.h
@@ -123,4 +123,30 @@ int32_t SignedInt_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls,
 int32_t UnsignedInt_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof);
 int32_t Float_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof);
 
+
+// compare operator
+int32_t Numeric_VecEq(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type);
+int32_t Decimal64_VecEQ(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+int32_t Decimal128_VecEQ(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+
+int32_t Numeric_VecNe(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type);
+int32_t Decimal64_VecNE(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+int32_t Decimal128_VecNE(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+
+int32_t Numeric_VecGt(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type);
+int32_t Decimal64_VecGT(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+int32_t Decimal128_VecGT(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+
+int32_t Numeric_VecGe(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type);
+int32_t Decimal64_VecGE(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+int32_t Decimal128_VecGE(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+
+int32_t Numeric_VecLt(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type);
+int32_t Decimal64_VecLT(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+int32_t Decimal128_VecLT(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+
+int32_t Numeric_VecLe(void *r, void *a, void  *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type);
+int32_t Decimal64_VecLE(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+int32_t Decimal128_VecLE(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag);
+
 #endif /* _MO_H_ */
diff --git a/cgo/mo_impl.h b/cgo/mo_impl.h
index cb9831a4c0894ad15e93417c275671829ba4243f..4dd259c6e6a85cdc495e52186fd8ee8bfef947c8 100644
--- a/cgo/mo_impl.h
+++ b/cgo/mo_impl.h
@@ -20,6 +20,8 @@
 #include "mo.h"
 
 #include <stdlib.h>
+#include <stdbool.h>
+#include <math.h>
 
 static const int32_t RC_SUCCESS = 0;
 static const int32_t RC_INFO = 1;
@@ -32,6 +34,10 @@ static const int32_t RC_OUT_OF_RANGE = 2001;
 static const int32_t RC_DATA_TRUNCATED = 2002;
 static const int32_t RC_INVALID_ARGUMENT = 2003;
 
+static const int32_t LEFT_IS_SCALAR = 1;
+static const int32_t RIGHT_IS_SCALAR = 2;
+
+
 #include "bitmap.h"
 
 #endif /* _MO_IMPL_H_ */
diff --git a/pkg/sql/plan/function/operator/compare.go b/pkg/sql/plan/function/operator/compare.go
index aa391fd2a7972a252081391636e557f9553591df..49b32a2028c6e4fe40dd1b076fdd74d8d719170a 100644
--- a/pkg/sql/plan/function/operator/compare.go
+++ b/pkg/sql/plan/function/operator/compare.go
@@ -16,53 +16,22 @@ package operator
 
 import (
 	"bytes"
-
 	"github.com/matrixorigin/matrixone/pkg/common/moerr"
 	"github.com/matrixorigin/matrixone/pkg/container/nulls"
 	"github.com/matrixorigin/matrixone/pkg/container/types"
 	"github.com/matrixorigin/matrixone/pkg/container/vector"
 	"github.com/matrixorigin/matrixone/pkg/encoding"
+	"github.com/matrixorigin/matrixone/pkg/vectorize/compare"
 	"github.com/matrixorigin/matrixone/pkg/vm/process"
 	"golang.org/x/exp/constraints"
 )
 
-var boolType = types.T_bool.ToType()
-
-type CompEq[T constraints.Integer | constraints.Float] struct{}
-type CompGe[T constraints.Integer | constraints.Float] struct{}
-type CompGt[T constraints.Integer | constraints.Float] struct{}
-type CompLe[T constraints.Integer | constraints.Float] struct{}
-type CompLt[T constraints.Integer | constraints.Float] struct{}
-type CompNe[T constraints.Integer | constraints.Float] struct{}
-
-type CompOp[T constraints.Integer | constraints.Float] interface {
-	CompEq[T] | CompGe[T] | CompGt[T] | CompLe[T] | CompLt[T] | CompNe[T]
-	Eval(a, b T) bool
-}
-
-func (c CompEq[T]) Eval(a, b T) bool {
-	return a == b
-}
-
-func (c CompGe[T]) Eval(a, b T) bool {
-	return a >= b
-}
-
-func (c CompGt[T]) Eval(a, b T) bool {
-	return a > b
+type compareT interface {
+	constraints.Integer | constraints.Float | bool |
+		types.Date | types.Datetime | types.Timestamp
 }
 
-func (c CompLe[T]) Eval(a, b T) bool {
-	return a <= b
-}
-
-func (c CompLt[T]) Eval(a, b T) bool {
-	return a < b
-}
-
-func (c CompNe[T]) Eval(a, b T) bool {
-	return a != b
-}
+var boolType = types.T_bool.ToType()
 
 func handleScalarNull(v1, v2 *vector.Vector, proc *process.Process) (*vector.Vector, error) {
 	if v1.IsScalarNull() {
@@ -83,168 +52,115 @@ func allocateBoolVector(length int, proc *process.Process) *vector.Vector {
 	return vec
 }
 
-func CompareOrdered[T constraints.Integer | constraints.Float, C CompOp[T]](c C, vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	v1, v2 := vs[0], vs[1]
-	col1, col2 := vector.MustTCols[T](v1), vector.MustTCols[T](v2)
-	if v1.IsScalarNull() || v2.IsScalarNull() {
-		return handleScalarNull(v1, v2, proc)
-	}
+type compareFn func(v1, v2, r *vector.Vector) error
 
-	if v1.IsScalar() && v2.IsScalar() {
-		vec := proc.AllocScalarVector(boolType)
-		vec.Col = make([]bool, 1)
-		vec.Col.([]bool)[0] = c.Eval(col1[0], col2[0])
-		return vec, nil
+func CompareOrdered(vs []*vector.Vector, proc *process.Process, cfn compareFn) (*vector.Vector, error) {
+	left, right := vs[0], vs[1]
+
+	if left.IsScalarNull() || right.IsScalarNull() {
+		return handleScalarNull(left, right, proc)
 	}
 
-	if v1.IsScalar() {
-		val1 := col1[0]
-		length := vector.Length(v2)
-		vec := allocateBoolVector(length, proc)
-		veccol := vec.Col.([]bool)
-		for i := range veccol {
-			veccol[i] = c.Eval(val1, col2[i])
+	if left.IsScalar() && right.IsScalar() {
+		resultVector := proc.AllocScalarVector(boolType)
+		if err := cfn(left, right, resultVector); err != nil {
+			return nil, err
 		}
-		nulls.Or(v2.Nsp, nil, vec.Nsp)
-		return vec, nil
+		return resultVector, nil
 	}
 
-	if v2.IsScalar() {
-		val2 := col2[0]
-		length := vector.Length(v1)
-		vec := allocateBoolVector(length, proc)
-		veccol := vec.Col.([]bool)
-		for i := range veccol {
-			veccol[i] = c.Eval(col1[i], val2)
-		}
-		nulls.Or(v1.Nsp, nil, vec.Nsp)
-		return vec, nil
+	length := vector.Length(left)
+	if left.IsScalar() {
+		length = vector.Length(right)
 	}
+	resultVector := allocateBoolVector(length, proc)
+	nulls.Or(left.Nsp, right.Nsp, resultVector.Nsp)
 
-	// Vec Vec
-	length := vector.Length(v1)
-	vec := allocateBoolVector(length, proc)
-	veccol := vec.Col.([]bool)
-	for i := range veccol {
-		veccol[i] = c.Eval(col1[i], col2[i])
+	if err := cfn(left, right, resultVector); err != nil {
+		return nil, err
 	}
-	nulls.Or(v1.Nsp, v2.Nsp, vec.Nsp)
-	return vec, nil
+	return resultVector, nil
 }
 
-type compFnType interface {
-	bool | types.Decimal64 | types.Decimal128
+// Equal compare operator
+func EqGeneral[T compareT](args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.NumericEqual[T])
 }
 
-type compFn[T compFnType] func(v1, v2 T, s1, s2 int32) bool
-
-func CompareWithFn[T compFnType](vs []*vector.Vector, fn compFn[T], proc *process.Process) (*vector.Vector, error) {
-	v1, v2 := vs[0], vs[1]
-
-	col1, col2 := vector.MustTCols[T](v1), vector.MustTCols[T](v2)
-	if v1.IsScalarNull() || v2.IsScalarNull() {
-		return handleScalarNull(v1, v2, proc)
-	}
-
-	if v1.IsScalar() && v2.IsScalar() {
-		vec := proc.AllocScalarVector(boolType)
-		vec.Col = make([]bool, 1)
-		vec.Col.([]bool)[0] = fn(col1[0], col2[0], v1.Typ.Scale, v2.Typ.Scale)
-		return vec, nil
-	}
-
-	if v1.IsScalar() {
-		val1 := col1[0]
-		length := vector.Length(v2)
-		vec := allocateBoolVector(length, proc)
-		veccol := vec.Col.([]bool)
-		for i := range veccol {
-			veccol[i] = fn(val1, col2[i], v1.Typ.Scale, v2.Typ.Scale)
-		}
-		nulls.Or(v2.Nsp, nil, vec.Nsp)
-		return vec, nil
-	}
-
-	if v2.IsScalar() {
-		val2 := col2[0]
-		length := vector.Length(v1)
-		vec := allocateBoolVector(length, proc)
-		veccol := vec.Col.([]bool)
-		for i := range veccol {
-			veccol[i] = fn(col1[i], val2, v1.Typ.Scale, v2.Typ.Scale)
-		}
-		nulls.Or(v1.Nsp, nil, vec.Nsp)
-		return vec, nil
-	}
-
-	// Vec Vec
-	length := vector.Length(v1)
-	vec := allocateBoolVector(length, proc)
-	veccol := vec.Col.([]bool)
-	for i := range veccol {
-		veccol[i] = fn(col1[i], col2[i], v1.Typ.Scale, v2.Typ.Scale)
-	}
-	nulls.Or(v1.Nsp, v2.Nsp, vec.Nsp)
-	return vec, nil
+func EqDecimal64(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal64VecEq)
 }
 
-func CompareDecimal64Eq(v1, v2 types.Decimal64, s1, s2 int32) bool {
-	return types.CompareDecimal64Decimal64(v1, v2, s1, s2) == 0
-}
-func CompareDecimal64Le(v1, v2 types.Decimal64, s1, s2 int32) bool {
-	return types.CompareDecimal64Decimal64(v1, v2, s1, s2) <= 0
+func EqDecimal128(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal128VecEq)
 }
-func CompareDecimal64Lt(v1, v2 types.Decimal64, s1, s2 int32) bool {
-	return types.CompareDecimal64Decimal64(v1, v2, s1, s2) < 0
-}
-func CompareDecimal64Ge(v1, v2 types.Decimal64, s1, s2 int32) bool {
-	return types.CompareDecimal64Decimal64(v1, v2, s1, s2) >= 0
+
+// Not Equal compare operator
+func NeGeneral[T compareT](args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.NumericNotEqual[T])
 }
-func CompareDecimal64Gt(v1, v2 types.Decimal64, s1, s2 int32) bool {
-	return types.CompareDecimal64Decimal64(v1, v2, s1, s2) > 0
+
+func NeDecimal64(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal64VecNe)
 }
-func CompareDecimal64Ne(v1, v2 types.Decimal64, s1, s2 int32) bool {
-	return types.CompareDecimal64Decimal64(v1, v2, s1, s2) != 0
+
+func NeDecimal128(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal128VecNe)
 }
 
-func CompareDecimal128Eq(v1, v2 types.Decimal128, s1, s2 int32) bool {
-	return types.CompareDecimal128Decimal128(v1, v2, s1, s2) == 0
+// Great than operator
+func GtGeneral[T compareT](args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.NumericGreatThan[T])
 }
-func CompareDecimal128Le(v1, v2 types.Decimal128, s1, s2 int32) bool {
-	return types.CompareDecimal128Decimal128(v1, v2, s1, s2) <= 0
+
+func GtDecimal64(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal64VecGt)
 }
-func CompareDecimal128Lt(v1, v2 types.Decimal128, s1, s2 int32) bool {
-	return types.CompareDecimal128Decimal128(v1, v2, s1, s2) < 0
+
+func GtDecimal128(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal128VecGt)
 }
-func CompareDecimal128Ge(v1, v2 types.Decimal128, s1, s2 int32) bool {
-	return types.CompareDecimal128Decimal128(v1, v2, s1, s2) >= 0
+
+// Great equal operator
+func GeGeneral[T compareT](args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.NumericGreatEqual[T])
 }
-func CompareDecimal128Gt(v1, v2 types.Decimal128, s1, s2 int32) bool {
-	return types.CompareDecimal128Decimal128(v1, v2, s1, s2) > 0
+
+func GeDecimal64(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal64VecGe)
 }
-func CompareDecimal128Ne(v1, v2 types.Decimal128, s1, s2 int32) bool {
-	return types.CompareDecimal128Decimal128(v1, v2, s1, s2) != 0
+
+func GeDecimal128(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal128VecGe)
 }
 
-func CompareBoolEq(v1, v2 bool, s1, s2 int32) bool {
-	return v1 == v2
+// less than operator
+func LtGeneral[T compareT](args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.NumericLessThan[T])
 }
-func CompareBoolLe(v1, v2 bool, s1, s2 int32) bool {
-	return (!v1) || v2
+
+func LtDecimal64(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal64VecLt)
 }
-func CompareBoolLt(v1, v2 bool, s1, s2 int32) bool {
-	return (!v1) && v2
+
+func LtDecimal128(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal128VecLt)
 }
-func CompareBoolGe(v1, v2 bool, s1, s2 int32) bool {
-	return v1 || (!v2)
+
+// less equal operator
+func LeGeneral[T compareT](args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.NumericLessEqual[T])
 }
-func CompareBoolGt(v1, v2 bool, s1, s2 int32) bool {
-	return v1 && (!v2)
+
+func LeDecimal64(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal64VecLe)
 }
-func CompareBoolNe(v1, v2 bool, s1, s2 int32) bool {
-	return v1 != v2
+
+func LeDecimal128(args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	return CompareOrdered(args, proc, compare.Decimal128VecLe)
 }
 
+// string compare
 type compStringFn func(v1, v2 []byte, s1, s2 int32) bool
 
 func CompareBytesEq(v1, v2 []byte, s1, s2 int32) bool {
@@ -313,128 +229,26 @@ func CompareString(vs []*vector.Vector, fn compStringFn, proc *process.Process)
 	return vec, nil
 }
 
-func EqGeneral[T constraints.Integer | constraints.Float](vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	var c CompEq[T]
-	return CompareOrdered[T](c, vs, proc)
-}
-
-func EqDecimal64(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal64Eq, proc)
-}
-
-func EqDecimal128(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal128Eq, proc)
-}
-
-func EqBool(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareBoolEq, proc)
-}
-
 func EqString(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
 	return CompareString(vs, CompareBytesEq, proc)
 }
 
-func LeGeneral[T constraints.Integer | constraints.Float](vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	var c CompLe[T]
-	return CompareOrdered[T](c, vs, proc)
-}
-
-func LeDecimal64(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal64Le, proc)
-}
-
-func LeDecimal128(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal128Le, proc)
-}
-
-func LeBool(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareBoolLe, proc)
-}
-
 func LeString(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
 	return CompareString(vs, CompareBytesLe, proc)
 }
 
-func LtGeneral[T constraints.Integer | constraints.Float](vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	var c CompLt[T]
-	return CompareOrdered[T](c, vs, proc)
-}
-
-func LtDecimal64(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal64Lt, proc)
-}
-
-func LtDecimal128(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal128Lt, proc)
-}
-
-func LtBool(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareBoolLt, proc)
-}
-
 func LtString(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
 	return CompareString(vs, CompareBytesLt, proc)
 }
 
-func GeGeneral[T constraints.Integer | constraints.Float](vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	var c CompGe[T]
-	return CompareOrdered[T](c, vs, proc)
-}
-
-func GeDecimal64(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal64Ge, proc)
-}
-
-func GeDecimal128(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal128Ge, proc)
-}
-
-func GeBool(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareBoolGe, proc)
-}
-
 func GeString(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
 	return CompareString(vs, CompareBytesGe, proc)
 }
 
-func GtGeneral[T constraints.Integer | constraints.Float](vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	var c CompGt[T]
-	return CompareOrdered[T](c, vs, proc)
-}
-
-func GtDecimal64(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal64Gt, proc)
-}
-
-func GtDecimal128(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal128Gt, proc)
-}
-
-func GtBool(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareBoolGt, proc)
-}
-
 func GtString(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
 	return CompareString(vs, CompareBytesGt, proc)
 }
 
-func NeGeneral[T constraints.Integer | constraints.Float](vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	var c CompNe[T]
-	return CompareOrdered[T](c, vs, proc)
-}
-
-func NeDecimal64(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal64Ne, proc)
-}
-
-func NeDecimal128(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareDecimal128Ne, proc)
-}
-
-func NeBool(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
-	return CompareWithFn(vs, CompareBoolNe, proc)
-}
-
 func NeString(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
 	return CompareString(vs, CompareBytesNe, proc)
 }
diff --git a/pkg/sql/plan/function/operators.go b/pkg/sql/plan/function/operators.go
index a15868fb9b513442d51b3ddd4d9f3e34ad59c77e..30f3cb190be16af657ec1abef17c11f3a00e348f 100644
--- a/pkg/sql/plan/function/operators.go
+++ b/pkg/sql/plan/function/operators.go
@@ -633,7 +633,7 @@ var operators = map[int]Functions{
 					types.T_bool,
 				},
 				ReturnTyp: types.T_bool,
-				Fn:        operator.EqBool,
+				Fn:        operator.EqGeneral[bool],
 			},
 			{
 				Index:  17,
@@ -849,7 +849,7 @@ var operators = map[int]Functions{
 					types.T_bool,
 				},
 				ReturnTyp: types.T_bool,
-				Fn:        operator.GtBool,
+				Fn:        operator.GtGeneral[bool],
 			},
 			{
 				Index:  17,
@@ -1065,7 +1065,7 @@ var operators = map[int]Functions{
 					types.T_bool,
 				},
 				ReturnTyp: types.T_bool,
-				Fn:        operator.GeBool,
+				Fn:        operator.GeGeneral[bool],
 			},
 			{
 				Index:  17,
@@ -1281,7 +1281,7 @@ var operators = map[int]Functions{
 					types.T_bool,
 				},
 				ReturnTyp: types.T_bool,
-				Fn:        operator.LtBool,
+				Fn:        operator.LtGeneral[bool],
 			},
 			{
 				Index:  17,
@@ -1497,7 +1497,7 @@ var operators = map[int]Functions{
 					types.T_bool,
 				},
 				ReturnTyp: types.T_bool,
-				Fn:        operator.LeBool,
+				Fn:        operator.LeGeneral[bool],
 			},
 			{
 				Index:  17,
@@ -1713,7 +1713,7 @@ var operators = map[int]Functions{
 					types.T_bool,
 				},
 				ReturnTyp: types.T_bool,
-				Fn:        operator.NeBool,
+				Fn:        operator.NeGeneral[bool],
 			},
 			{
 				Index:  17,
diff --git a/pkg/vectorize/compare/compare.go b/pkg/vectorize/compare/compare.go
new file mode 100644
index 0000000000000000000000000000000000000000..6bc75ab18b22dbf75caa5f13e2b318c09368e3a6
--- /dev/null
+++ b/pkg/vectorize/compare/compare.go
@@ -0,0 +1,277 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compare
+
+/*
+   #include "mo.h"
+
+   #cgo CFLAGS: -I../../../cgo
+   #cgo LDFLAGS: -L../../../cgo -lmo -lm
+*/
+import "C"
+
+import (
+	"github.com/matrixorigin/matrixone/pkg/common/moerr"
+	"github.com/matrixorigin/matrixone/pkg/container/nulls"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"golang.org/x/exp/constraints"
+	"unsafe"
+)
+
+const (
+	LEFT_IS_SCALAR  = 1
+	RIGHT_IS_SCALAR = 2
+)
+
+func dec64PtrToC(p *types.Decimal64) *C.int64_t {
+	return (*C.int64_t)(unsafe.Pointer(p))
+}
+func dec128PtrToC(p *types.Decimal128) *C.int64_t {
+	return (*C.int64_t)(unsafe.Pointer(p))
+}
+
+func GetScalarFlag(xs, ys, rs *vector.Vector) int {
+	flag := 0
+	if xs.IsScalar() {
+		flag |= LEFT_IS_SCALAR
+	}
+	if ys.IsScalar() {
+		flag |= RIGHT_IS_SCALAR
+	}
+	return flag
+}
+
+func NumericEqual[T constraints.Integer | constraints.Float | bool](xs, ys, rs *vector.Vector) error {
+	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Numeric_VecEq(unsafe.Pointer(&rt[0]), unsafe.Pointer(&xt[0]), unsafe.Pointer(&yt[0]), C.uint64_t(len(rt)),
+		(*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag), C.int32_t(int32(xs.Typ.Oid)))
+	if rc != 0 {
+		return moerr.NewError(moerr.INVALID_ARGUMENT, "invalid input type")
+	}
+	return nil
+}
+
+func NumericNotEqual[T constraints.Integer | constraints.Float | bool](xs, ys, rs *vector.Vector) error {
+	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Numeric_VecNe(unsafe.Pointer(&rt[0]), unsafe.Pointer(&xt[0]), unsafe.Pointer(&yt[0]), C.uint64_t(len(rt)),
+		(*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag), C.int32_t(int32(xs.Typ.Oid)))
+	if rc != 0 {
+		return moerr.NewError(moerr.INVALID_ARGUMENT, "invalid input type")
+	}
+	return nil
+}
+
+func NumericGreatThan[T constraints.Integer | constraints.Float | bool](xs, ys, rs *vector.Vector) error {
+	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Numeric_VecGt(unsafe.Pointer(&rt[0]), unsafe.Pointer(&xt[0]), unsafe.Pointer(&yt[0]), C.uint64_t(len(rt)),
+		(*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag), C.int32_t(int32(xs.Typ.Oid)))
+	if rc != 0 {
+		return moerr.NewError(moerr.INVALID_ARGUMENT, "invalid input type")
+	}
+	return nil
+}
+
+func NumericGreatEqual[T constraints.Integer | constraints.Float | bool](xs, ys, rs *vector.Vector) error {
+	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Numeric_VecGe(unsafe.Pointer(&rt[0]), unsafe.Pointer(&xt[0]), unsafe.Pointer(&yt[0]), C.uint64_t(len(rt)),
+		(*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag), C.int32_t(int32(xs.Typ.Oid)))
+	if rc != 0 {
+		return moerr.NewError(moerr.INVALID_ARGUMENT, "invalid input type")
+	}
+	return nil
+}
+
+func NumericLessThan[T constraints.Integer | constraints.Float | bool](xs, ys, rs *vector.Vector) error {
+	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Numeric_VecLt(unsafe.Pointer(&rt[0]), unsafe.Pointer(&xt[0]), unsafe.Pointer(&yt[0]), C.uint64_t(len(rt)),
+		(*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag), C.int32_t(int32(xs.Typ.Oid)))
+	if rc != 0 {
+		return moerr.NewError(moerr.INVALID_ARGUMENT, "invalid input type")
+	}
+	return nil
+}
+
+func NumericLessEqual[T constraints.Integer | constraints.Float | bool](xs, ys, rs *vector.Vector) error {
+	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Numeric_VecLe(unsafe.Pointer(&rt[0]), unsafe.Pointer(&xt[0]), unsafe.Pointer(&yt[0]), C.uint64_t(len(rt)),
+		(*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag), C.int32_t(int32(xs.Typ.Oid)))
+	if rc != 0 {
+		return moerr.NewError(moerr.INVALID_ARGUMENT, "invalid input type")
+	}
+	return nil
+}
+
+func Decimal64VecEq(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal64](xs)
+	yt := vector.MustTCols[types.Decimal64](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal64_VecEQ((*C.bool)(&rt[0]), dec64PtrToC(&xt[0]), dec64PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal64 euqal error")
+	}
+	return nil
+}
+
+func Decimal128VecEq(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal128](xs)
+	yt := vector.MustTCols[types.Decimal128](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal128_VecEQ((*C.bool)(&rt[0]), dec128PtrToC(&xt[0]), dec128PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal128 equal error")
+	}
+	return nil
+}
+
+func Decimal64VecNe(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal64](xs)
+	yt := vector.MustTCols[types.Decimal64](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal64_VecNE((*C.bool)(&rt[0]), dec64PtrToC(&xt[0]), dec64PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal64 not euqal error")
+	}
+	return nil
+}
+
+func Decimal128VecNe(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal128](xs)
+	yt := vector.MustTCols[types.Decimal128](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal128_VecNE((*C.bool)(&rt[0]), dec128PtrToC(&xt[0]), dec128PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal128 not equal error")
+	}
+	return nil
+}
+
+func Decimal64VecGt(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal64](xs)
+	yt := vector.MustTCols[types.Decimal64](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal64_VecGT((*C.bool)(&rt[0]), dec64PtrToC(&xt[0]), dec64PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal64 great than error")
+	}
+	return nil
+}
+
+func Decimal128VecGt(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal128](xs)
+	yt := vector.MustTCols[types.Decimal128](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal128_VecGT((*C.bool)(&rt[0]), dec128PtrToC(&xt[0]), dec128PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal128 great than error")
+	}
+	return nil
+}
+
+func Decimal64VecGe(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal64](xs)
+	yt := vector.MustTCols[types.Decimal64](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal64_VecGE((*C.bool)(&rt[0]), dec64PtrToC(&xt[0]), dec64PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal64 great equal error")
+	}
+	return nil
+}
+
+func Decimal128VecGe(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal128](xs)
+	yt := vector.MustTCols[types.Decimal128](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal128_VecGE((*C.bool)(&rt[0]), dec128PtrToC(&xt[0]), dec128PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal128 great equal error")
+	}
+	return nil
+}
+
+func Decimal64VecLt(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal64](xs)
+	yt := vector.MustTCols[types.Decimal64](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal64_VecLT((*C.bool)(&rt[0]), dec64PtrToC(&xt[0]), dec64PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal64 less than error")
+	}
+	return nil
+}
+
+func Decimal128VecLt(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal128](xs)
+	yt := vector.MustTCols[types.Decimal128](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal128_VecLT((*C.bool)(&rt[0]), dec128PtrToC(&xt[0]), dec128PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal128 less than error")
+	}
+	return nil
+}
+
+func Decimal64VecLe(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal64](xs)
+	yt := vector.MustTCols[types.Decimal64](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal64_VecLE((*C.bool)(&rt[0]), dec64PtrToC(&xt[0]), dec64PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal64 less euqal error")
+	}
+	return nil
+}
+
+func Decimal128VecLe(xs, ys, rs *vector.Vector) error {
+	xt := vector.MustTCols[types.Decimal128](xs)
+	yt := vector.MustTCols[types.Decimal128](ys)
+	rt := vector.MustTCols[bool](rs)
+	flag := GetScalarFlag(xs, ys, rs)
+	rc := C.Decimal128_VecLE((*C.bool)(&rt[0]), dec128PtrToC(&xt[0]), dec128PtrToC(&yt[0]),
+		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag))
+	if rc != 0 {
+		return moerr.NewError(moerr.OUT_OF_RANGE, "Decimal128 less equal error")
+	}
+	return nil
+}
diff --git a/pkg/vectorize/compare/equal_test.go b/pkg/vectorize/compare/equal_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..119986d4eaab94d5a56a78a9fe3abd42e9f8f3e1
--- /dev/null
+++ b/pkg/vectorize/compare/equal_test.go
@@ -0,0 +1,325 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compare
+
+import (
+	"fmt"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/testutil"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestI32Eq(t *testing.T) {
+	as := make([]int32, 10)
+	bs := make([]int32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 4
+		bs[i] = int32(i - 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeInt32Vector(as, nil)
+	bv := testutil.MakeInt32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericEqual[int32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v == %+v \n", as[i], bs[i])
+		fmt.Printf("actual res:%+v\n", res[i])
+		fmt.Printf("expect res:%+v\n", as[i] == bs[i])
+		if res[i] != (as[i] == bs[i]) {
+			t.Fatalf("int32 equal wrong result")
+		}
+	}
+}
+
+func TestU32Eq(t *testing.T) {
+	as := make([]uint32, 10)
+	bs := make([]uint32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 8
+		bs[i] = uint32(i + 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeUint32Vector(as, nil)
+	bv := testutil.MakeUint32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericEqual[uint32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v == %+v \n", as[i], bs[i])
+		fmt.Printf("actual res:%+v\n", res[i])
+		fmt.Printf("expect res:%+v\n", as[i] == bs[i])
+		if res[i] != (as[i] == bs[i]) {
+			t.Fatalf("uint32 equal wrong result")
+		}
+	}
+}
+
+func TestF32Eq(t *testing.T) {
+	as := make([]float32, 2)
+	bs := make([]float32, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = 2.5
+		bs[i] = float32(i) + 1.5
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeFloat32Vector(as, nil)
+	bv := testutil.MakeFloat32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericEqual[float32](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		//fmt.Printf("%+v == %+v \n", as[i], bs[i])
+		//fmt.Printf("actual res:%+v\n", res[i])
+		//fmt.Printf("expect res:%+v\n", as[i] == bs[i])
+		if res[i] != (as[i] == bs[i]) {
+			t.Fatalf("float32 equal wrong result")
+		}
+	}
+}
+
+func TestF64Eq(t *testing.T) {
+	as := make([]float64, 2)
+	bs := make([]float64, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = 2.5
+		bs[i] = float64(i) + 1.5
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeFloat64Vector(as, nil)
+	bv := testutil.MakeFloat64Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericEqual[float64](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		//fmt.Printf("%+v == %+v \n", as[i], bs[i])
+		//fmt.Printf("actual res:%+v\n", res[i])
+		//fmt.Printf("expect res:%+v\n", as[i] == bs[i])
+		if res[i] != (as[i] == bs[i]) {
+			t.Fatalf("float32 equal wrong result")
+		}
+	}
+}
+
+func TestBoolEq(t *testing.T) {
+	as := make([]bool, 2)
+	bs := make([]bool, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = true
+		bs[i] = false
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeBoolVector(as)
+	bv := testutil.MakeBoolVector(bs)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericEqual[bool](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v == %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, as[i] == bs[i], res[i])
+	}
+}
+
+func TestDec64Eq(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal64Vector(as, nil, types.T_decimal64.ToType())
+	bv := testutil.MakeDecimal64Vector(bs, nil, types.T_decimal64.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal64VecEq(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal64 equal failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v == %+v \n", as[i], bs[i])
+		fmt.Printf("actual res:%+v\n", res[i])
+		fmt.Printf("expect res:%+v\n", as[i] == bs[i])
+		if res[i] != (as[i] == bs[i]) {
+			t.Fatalf("decimal64 equal wrong result")
+		}
+	}
+}
+
+func TestDec128Eq(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal128Vector(as, nil, types.T_decimal128.ToType())
+	bv := testutil.MakeDecimal128Vector(bs, nil, types.T_decimal128.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal128VecEq(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal128 equal failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v == %+v \n", as[i], bs[i])
+		fmt.Printf("actual res:%+v\n", res[i])
+		fmt.Printf("expect res:%+v\n", as[i] == bs[i])
+		if res[i] != (as[i] == bs[i]) {
+			t.Fatalf("decimal128 equal wrong result")
+		}
+	}
+}
+
+// benach mark test
+
+func BenchmarkEqI32Eq_C(b *testing.B) {
+	as := make([]int32, 8192)
+	bs := make([]int32, 8192)
+	for i := 0; i < 8192; i++ {
+		as[i] = int32(i)
+		bs[i] = 1
+	}
+
+	cs := make([]bool, 8192)
+
+	av := testutil.MakeInt32Vector(as, nil)
+	bv := testutil.MakeInt32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	for i := 0; i < b.N; i++ {
+		if err := NumericEqual[int32](av, bv, cv); err != nil {
+			b.Fail()
+		}
+	}
+}
+
+func BenchmarkEqUI32Eq_C(b *testing.B) {
+	as := make([]uint32, 8192)
+	bs := make([]uint32, 8192)
+	for i := 0; i < 8192; i++ {
+		as[i] = uint32(i)
+		bs[i] = 1
+	}
+
+	cs := make([]bool, 8192)
+
+	av := testutil.MakeUint32Vector(as, nil)
+	bv := testutil.MakeUint32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	for i := 0; i < b.N; i++ {
+		if err := NumericEqual[uint32](av, bv, cv); err != nil {
+			b.Fail()
+		}
+	}
+}
+
+func BenchmarkEqF64Eq_C(b *testing.B) {
+	as := make([]float64, 8192)
+	bs := make([]float64, 8192)
+	for i := 0; i < 8192; i++ {
+		as[i] = float64(i)
+		bs[i] = 1
+	}
+
+	cs := make([]bool, 8192)
+
+	av := testutil.MakeFloat64Vector(as, nil)
+	bv := testutil.MakeFloat64Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	for i := 0; i < b.N; i++ {
+		if err := NumericEqual[float64](av, bv, cv); err != nil {
+			b.Fail()
+		}
+	}
+}
+
+func BenchmarkEqDec64(b *testing.B) {
+	as := make([]int64, 8192)
+	bs := make([]int64, 8192)
+	cs := make([]bool, 8192)
+	for i := 0; i < 8192; i++ {
+		as[i] = int64(i)
+		bs[i] = 1
+	}
+
+	av := testutil.MakeDecimal64Vector(as, nil, types.T_decimal64.ToType())
+	bv := testutil.MakeDecimal64Vector(bs, nil, types.T_decimal64.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	for i := 0; i < b.N; i++ {
+		if err := Decimal64VecEq(av, bv, cv); err != nil {
+			b.Fail()
+		}
+	}
+}
+
+func BenchmarkEqDec128(b *testing.B) {
+	as := make([]int64, 8192)
+	bs := make([]int64, 8192)
+	cs := make([]bool, 8192)
+	for i := 0; i < 8192; i++ {
+		as[i] = int64(i)
+		bs[i] = 1
+	}
+
+	av := testutil.MakeDecimal128Vector(as, nil, types.T_decimal64.ToType())
+	bv := testutil.MakeDecimal128Vector(bs, nil, types.T_decimal64.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	for i := 0; i < b.N; i++ {
+		if err := Decimal128VecEq(av, bv, cv); err != nil {
+			b.Fail()
+		}
+	}
+}
diff --git a/pkg/vectorize/compare/greatEqual_test.go b/pkg/vectorize/compare/greatEqual_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..2d0172b6395894132df4eafeb3b8f2ca8b930413
--- /dev/null
+++ b/pkg/vectorize/compare/greatEqual_test.go
@@ -0,0 +1,196 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compare
+
+import (
+	"fmt"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/testutil"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestI32Ge(t *testing.T) {
+	as := make([]int32, 10)
+	bs := make([]int32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 4
+		bs[i] = int32(i - 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeInt32Vector(as, nil)
+	bv := testutil.MakeInt32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericGreatEqual[int32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v >= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] >= bs[i], res[i])
+	}
+}
+
+func TestU32Ge(t *testing.T) {
+	as := make([]uint32, 10)
+	bs := make([]uint32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 8
+		bs[i] = uint32(i + 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeUint32Vector(as, nil)
+	bv := testutil.MakeUint32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericGreatEqual[uint32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v >= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] >= bs[i], res[i])
+	}
+}
+
+func TestF32Ge(t *testing.T) {
+	as := make([]float32, 10)
+	bs := make([]float32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 2.5
+		bs[i] = float32(i) + 1.5
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeFloat32Vector(as, nil)
+	bv := testutil.MakeFloat32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericGreatEqual[float32](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v >= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] >= bs[i], res[i])
+	}
+}
+
+func TestF64Ge(t *testing.T) {
+	as := make([]float64, 10)
+	bs := make([]float64, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 2.5
+		bs[i] = float64(i) + 1.5
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeFloat64Vector(as, nil)
+	bv := testutil.MakeFloat64Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericGreatEqual[float64](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v >= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] >= bs[i], res[i])
+	}
+}
+
+func TestBoolGe(t *testing.T) {
+	as := make([]bool, 2)
+	bs := make([]bool, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = true
+		bs[i] = false
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeBoolVector(as)
+	bv := testutil.MakeBoolVector(bs)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericGreatEqual[bool](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v >= %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, as[i] || !(bs[i]), res[i])
+	}
+}
+
+func TestDec64Ge(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i + 5)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal64Vector(as, nil, types.T_decimal64.ToType())
+	bv := testutil.MakeDecimal64Vector(bs, nil, types.T_decimal64.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal64VecGe(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal64 great equal failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v >= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] >= bs[i], res[i])
+	}
+}
+
+func TestDec128Ge(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal128Vector(as, nil, types.T_decimal128.ToType())
+	bv := testutil.MakeDecimal128Vector(bs, nil, types.T_decimal128.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal128VecGe(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal128 great equal failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v >= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] >= bs[i], res[i])
+	}
+}
diff --git a/pkg/vectorize/compare/greatThan_test.go b/pkg/vectorize/compare/greatThan_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..431ce0cdb6927adb42ddcd63c1ae94fa0a121aad
--- /dev/null
+++ b/pkg/vectorize/compare/greatThan_test.go
@@ -0,0 +1,196 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compare
+
+import (
+	"fmt"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/testutil"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestI32Gt(t *testing.T) {
+	as := make([]int32, 10)
+	bs := make([]int32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 4
+		bs[i] = int32(i - 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeInt32Vector(as, nil)
+	bv := testutil.MakeInt32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericGreatThan[int32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v > %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] > bs[i], res[i])
+	}
+}
+
+func TestU32Gt(t *testing.T) {
+	as := make([]uint32, 10)
+	bs := make([]uint32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 8
+		bs[i] = uint32(i + 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeUint32Vector(as, nil)
+	bv := testutil.MakeUint32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericGreatThan[uint32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v > %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] > bs[i], res[i])
+	}
+}
+
+func TestF32Gt(t *testing.T) {
+	as := make([]float32, 2)
+	bs := make([]float32, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = 2.5
+		bs[i] = float32(i) + 1.5
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeFloat32Vector(as, nil)
+	bv := testutil.MakeFloat32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericGreatThan[float32](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v > %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] > bs[i], res[i])
+	}
+}
+
+func TestF64Gt(t *testing.T) {
+	as := make([]float64, 2)
+	bs := make([]float64, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = 2.5
+		bs[i] = float64(i) + 1.5
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeFloat64Vector(as, nil)
+	bv := testutil.MakeFloat64Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericGreatThan[float64](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v > %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] > bs[i], res[i])
+	}
+}
+
+func TestBoolGt(t *testing.T) {
+	as := make([]bool, 2)
+	bs := make([]bool, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = true
+		bs[i] = false
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeBoolVector(as)
+	bv := testutil.MakeBoolVector(bs)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericGreatThan[bool](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v > %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, as[i] && !(bs[i]), res[i])
+	}
+}
+
+func TestDec64Gt(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i + 5)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal64Vector(as, nil, types.T_decimal64.ToType())
+	bv := testutil.MakeDecimal64Vector(bs, nil, types.T_decimal64.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal64VecGt(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal64 great than failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v > %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] > bs[i], res[i])
+	}
+}
+
+func TestDec128Gt(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal128Vector(as, nil, types.T_decimal128.ToType())
+	bv := testutil.MakeDecimal128Vector(bs, nil, types.T_decimal128.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal128VecGt(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal128 great than failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v > %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] > bs[i], res[i])
+	}
+}
diff --git a/pkg/vectorize/compare/lessEqual_test.go b/pkg/vectorize/compare/lessEqual_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5623b1b60b8b8afb1899568a3f882190e038fddc
--- /dev/null
+++ b/pkg/vectorize/compare/lessEqual_test.go
@@ -0,0 +1,196 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compare
+
+import (
+	"fmt"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/testutil"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestI32Le(t *testing.T) {
+	as := make([]int32, 10)
+	bs := make([]int32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 4
+		bs[i] = int32(i - 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeInt32Vector(as, nil)
+	bv := testutil.MakeInt32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericLessEqual[int32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v <= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] <= bs[i], res[i])
+	}
+}
+
+func TestU32Le(t *testing.T) {
+	as := make([]uint32, 10)
+	bs := make([]uint32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 8
+		bs[i] = uint32(i + 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeUint32Vector(as, nil)
+	bv := testutil.MakeUint32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericLessEqual[uint32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v <= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] <= bs[i], res[i])
+	}
+}
+
+func TestF32Le(t *testing.T) {
+	as := make([]float32, 2)
+	bs := make([]float32, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = 2.5
+		bs[i] = float32(i) + 1.5
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeFloat32Vector(as, nil)
+	bv := testutil.MakeFloat32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericLessEqual[float32](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v <= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] <= bs[i], res[i])
+	}
+}
+
+func TestF64Le(t *testing.T) {
+	as := make([]float64, 2)
+	bs := make([]float64, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = 2.5
+		bs[i] = float64(i) + 1.5
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeFloat64Vector(as, nil)
+	bv := testutil.MakeFloat64Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericLessEqual[float64](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v <= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] <= bs[i], res[i])
+	}
+}
+
+func TestBoolLe(t *testing.T) {
+	as := make([]bool, 2)
+	bs := make([]bool, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = true
+		bs[i] = false
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeBoolVector(as)
+	bv := testutil.MakeBoolVector(bs)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericLessEqual[bool](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v <= %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, !(as[i]) || bs[i], res[i])
+	}
+}
+
+func TestDec64Le(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i + 5)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal64Vector(as, nil, types.T_decimal64.ToType())
+	bv := testutil.MakeDecimal64Vector(bs, nil, types.T_decimal64.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal64VecLe(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal64 less equal failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v <= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] <= bs[i], res[i])
+	}
+}
+
+func TestDec128Le(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal128Vector(as, nil, types.T_decimal128.ToType())
+	bv := testutil.MakeDecimal128Vector(bs, nil, types.T_decimal128.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal128VecLe(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal128 less equal failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v <= %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] <= bs[i], res[i])
+	}
+}
diff --git a/pkg/vectorize/compare/lessThan_test.go b/pkg/vectorize/compare/lessThan_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..4f4f2c1d152006601b66e3e7c8929a212631239b
--- /dev/null
+++ b/pkg/vectorize/compare/lessThan_test.go
@@ -0,0 +1,196 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compare
+
+import (
+	"fmt"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/testutil"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestI32Lt(t *testing.T) {
+	as := make([]int32, 10)
+	bs := make([]int32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 4
+		bs[i] = int32(i - 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeInt32Vector(as, nil)
+	bv := testutil.MakeInt32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericLessThan[int32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v < %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] < bs[i], res[i])
+	}
+}
+
+func TestU32Lt(t *testing.T) {
+	as := make([]uint32, 10)
+	bs := make([]uint32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 8
+		bs[i] = uint32(i + 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeUint32Vector(as, nil)
+	bv := testutil.MakeUint32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericLessThan[uint32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v < %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] < bs[i], res[i])
+	}
+}
+
+func TestF32Lt(t *testing.T) {
+	as := make([]float32, 2)
+	bs := make([]float32, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = 2.5
+		bs[i] = float32(i) + 1.5
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeFloat32Vector(as, nil)
+	bv := testutil.MakeFloat32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericLessThan[float32](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v < %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] < bs[i], res[i])
+	}
+}
+
+func TestF64Lt(t *testing.T) {
+	as := make([]float64, 2)
+	bs := make([]float64, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = 2.5
+		bs[i] = float64(i) + 1.5
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeFloat64Vector(as, nil)
+	bv := testutil.MakeFloat64Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericLessThan[float64](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v < %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] < bs[i], res[i])
+	}
+}
+
+func TestBoolLt(t *testing.T) {
+	as := make([]bool, 2)
+	bs := make([]bool, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = true
+		bs[i] = false
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeBoolVector(as)
+	bv := testutil.MakeBoolVector(bs)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericLessThan[bool](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v < %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, !(as[i]) && bs[i], res[i])
+	}
+}
+
+func TestDec64Lt(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i + 5)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal64Vector(as, nil, types.T_decimal64.ToType())
+	bv := testutil.MakeDecimal64Vector(bs, nil, types.T_decimal64.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal64VecLt(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal64 less than failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v < %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] < bs[i], res[i])
+	}
+}
+
+func TestDec128Lt(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal128Vector(as, nil, types.T_decimal128.ToType())
+	bv := testutil.MakeDecimal128Vector(bs, nil, types.T_decimal128.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal128VecLt(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal128 less than failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v < %+v \n", as[i], bs[i])
+		assert.Equal(t, as[i] < bs[i], res[i])
+	}
+}
diff --git a/pkg/vectorize/compare/notEqual_test.go b/pkg/vectorize/compare/notEqual_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5e874d708e2fe0d6a923277656fc48e93fd46db7
--- /dev/null
+++ b/pkg/vectorize/compare/notEqual_test.go
@@ -0,0 +1,196 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compare
+
+import (
+	"fmt"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/testutil"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestI32Ne(t *testing.T) {
+	as := make([]int32, 10)
+	bs := make([]int32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 4
+		bs[i] = int32(i - 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeInt32Vector(as, nil)
+	bv := testutil.MakeInt32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericNotEqual[int32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v != %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, as[i] != bs[i], res[i])
+	}
+}
+
+func TestU32Ne(t *testing.T) {
+	as := make([]uint32, 10)
+	bs := make([]uint32, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = 8
+		bs[i] = uint32(i + 3)
+	}
+	cs := make([]bool, 10)
+	av := testutil.MakeUint32Vector(as, nil)
+	bv := testutil.MakeUint32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericNotEqual[uint32](av, bv, cv)
+	if err != nil {
+		t.Fatal(err)
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v != %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, as[i] != bs[i], res[i])
+	}
+}
+
+func TestF32Ne(t *testing.T) {
+	as := make([]float32, 2)
+	bs := make([]float32, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = 2.5
+		bs[i] = float32(i) + 1.5
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeFloat32Vector(as, nil)
+	bv := testutil.MakeFloat32Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericNotEqual[float32](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v != %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, as[i] != bs[i], res[i])
+	}
+}
+
+func TestF64Ne(t *testing.T) {
+	as := make([]float64, 2)
+	bs := make([]float64, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = 2.5
+		bs[i] = float64(i) + 1.5
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeFloat64Vector(as, nil)
+	bv := testutil.MakeFloat64Vector(bs, nil)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericNotEqual[float64](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v != %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, as[i] != bs[i], res[i])
+	}
+}
+
+func TestBoolNe(t *testing.T) {
+	as := make([]bool, 2)
+	bs := make([]bool, 2)
+	for i := 0; i < 2; i++ {
+		as[i] = true
+		bs[i] = false
+	}
+	cs := make([]bool, 2)
+	av := testutil.MakeBoolVector(as)
+	bv := testutil.MakeBoolVector(bs)
+	cv := testutil.MakeBoolVector(cs)
+
+	err := NumericNotEqual[bool](av, bv, cv)
+	if err != nil {
+		t.Fatalf("should not error.")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 2; i++ {
+		fmt.Printf("%+v != %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, as[i] != bs[i], res[i])
+	}
+}
+
+func TestDec64Ne(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal64Vector(as, nil, types.T_decimal64.ToType())
+	bv := testutil.MakeDecimal64Vector(bs, nil, types.T_decimal64.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal64VecNe(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal64 not equal failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v != %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, as[i] != bs[i], res[i])
+	}
+}
+
+func TestDec128Ne(t *testing.T) {
+	as := make([]int64, 10)
+	bs := make([]int64, 10)
+	cs := make([]bool, 10)
+	for i := 0; i < 10; i++ {
+		as[i] = int64(i)
+		bs[i] = int64(3 * i)
+	}
+
+	av := testutil.MakeDecimal128Vector(as, nil, types.T_decimal128.ToType())
+	bv := testutil.MakeDecimal128Vector(bs, nil, types.T_decimal128.ToType())
+	cv := testutil.MakeBoolVector(cs)
+
+	err := Decimal128VecNe(av, bv, cv)
+	if err != nil {
+		t.Fatalf("decimal128 not equal failed")
+	}
+
+	res := vector.MustTCols[bool](cv)
+	for i := 0; i < 10; i++ {
+		fmt.Printf("%+v != %+v : %v \n", as[i], bs[i], res[i])
+		assert.Equal(t, as[i] != bs[i], res[i])
+	}
+}