diff --git a/src/org/redkale/source/ColumnFuncNode.java b/src/org/redkale/source/ColumnFuncNode.java
new file mode 100644
index 000000000..c0ba981ec
--- /dev/null
+++ b/src/org/redkale/source/ColumnFuncNode.java
@@ -0,0 +1,83 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.redkale.source;
+
+import java.io.Serializable;
+
+/**
+ * 与ColumnNodeValue 组合,用于复杂的字段表达式 。
+ * String 视为 字段名
+ *
+ *
+ * 详情见: https://redkale.org
+ *
+ * @author zhangjx
+ * @since 2.0.0
+ */
+public class ColumnFuncNode implements ColumnNode {
+
+ protected FilterFunc func;
+
+ protected Serializable value;//类型只能是String、ColumnNodeValue
+
+ public ColumnFuncNode() {
+ }
+
+ public ColumnFuncNode(FilterFunc func, Serializable node) {
+ if (!(node instanceof String) && !(node instanceof ColumnNodeValue)) throw new IllegalArgumentException("value must be String or ColumnNodeValue");
+ this.func = func;
+ this.value = node;
+ }
+
+ public static ColumnFuncNode create(FilterFunc func, Serializable node) {
+ return new ColumnFuncNode(func, node);
+ }
+
+ public static ColumnFuncNode avg(Serializable node) {
+ return new ColumnFuncNode(FilterFunc.AVG, node);
+ }
+
+ public static ColumnFuncNode count(Serializable node) {
+ return new ColumnFuncNode(FilterFunc.COUNT, node);
+ }
+
+ public static ColumnFuncNode distinctCount(Serializable node) {
+ return new ColumnFuncNode(FilterFunc.DISTINCTCOUNT, node);
+ }
+
+ public static ColumnFuncNode max(Serializable node) {
+ return new ColumnFuncNode(FilterFunc.MAX, node);
+ }
+
+ public static ColumnFuncNode min(Serializable node) {
+ return new ColumnFuncNode(FilterFunc.MIN, node);
+ }
+
+ public static ColumnFuncNode sum(Serializable node) {
+ return new ColumnFuncNode(FilterFunc.SUM, node);
+ }
+
+ public FilterFunc getFunc() {
+ return func;
+ }
+
+ public void setFunc(FilterFunc func) {
+ this.func = func;
+ }
+
+ public Serializable getValue() {
+ return value;
+ }
+
+ public void setValue(Serializable value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"func\":\"" + func + "\", \"value\":" + ((value instanceof CharSequence) ? ("\"" + value + "\"") : value) + "}";
+ }
+}
diff --git a/src/org/redkale/source/ColumnNode.java b/src/org/redkale/source/ColumnNode.java
new file mode 100644
index 000000000..e73e69015
--- /dev/null
+++ b/src/org/redkale/source/ColumnNode.java
@@ -0,0 +1,21 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.redkale.source;
+
+import java.io.Serializable;
+
+/**
+ * ColumnFuncNode与ColumnNodeValue 的接口
+ *
+ *
+ * 详情见: https://redkale.org
+ *
+ * @author zhangjx
+ * @since 2.0.0
+ */
+public interface ColumnNode extends Serializable {
+
+}
diff --git a/src/org/redkale/source/ColumnNodeValue.java b/src/org/redkale/source/ColumnNodeValue.java
index 530c9dbd0..2deb9950e 100644
--- a/src/org/redkale/source/ColumnNodeValue.java
+++ b/src/org/redkale/source/ColumnNodeValue.java
@@ -13,21 +13,33 @@ import static org.redkale.source.ColumnExpress.*;
* String 视为 字段名
* Number 视为 数值
*
+ *
+ * 详情见: https://redkale.org
+ *
* @author zhangjx
+ * @since 2.0.0
*/
-public class ColumnNodeValue implements Serializable {
+public class ColumnNodeValue implements ColumnNode {
- private Serializable left;//类型只能是String、Number、ColumnNodeValue
+ protected Serializable left;//类型只能是String、Number、ColumnNodeValue
- private ColumnExpress express; //不能是MOV
+ protected ColumnExpress express; //不能是MOV
- private Serializable right;//类型只能是String、Number、ColumnNodeValue
+ protected Serializable right;//类型只能是String、Number、ColumnNodeValue
public ColumnNodeValue() {
}
public ColumnNodeValue(Serializable left, ColumnExpress express, Serializable right) {
- if (express == null || express == ColumnExpress.MOV) throw new IllegalArgumentException("express cannot be null or MOV");
+ if (express == null || express == ColumnExpress.MOV) {
+ throw new IllegalArgumentException("express cannot be null or MOV");
+ }
+ if (!(left instanceof String) && !(left instanceof Number) && !(left instanceof ColumnNodeValue) && !(left instanceof ColumnFuncNode)) {
+ throw new IllegalArgumentException("left value must be String, Number, ColumnFuncNode or ColumnNodeValue");
+ }
+ if (!(right instanceof String) && !(right instanceof Number) && !(right instanceof ColumnNodeValue) && !(right instanceof ColumnFuncNode)) {
+ throw new IllegalArgumentException("right value must be String, Number, ColumnFuncNode or ColumnNodeValue");
+ }
this.left = left;
this.express = express;
this.right = right;
@@ -72,7 +84,7 @@ public class ColumnNodeValue implements Serializable {
public ColumnNodeValue dec(Serializable right) {
return any(DEC, right);
}
-
+
public ColumnNodeValue mul(Serializable right) {
return any(MUL, right);
}
diff --git a/src/org/redkale/source/DataJdbcSource.java b/src/org/redkale/source/DataJdbcSource.java
index 65fd23f20..5a977b203 100644
--- a/src/org/redkale/source/DataJdbcSource.java
+++ b/src/org/redkale/source/DataJdbcSource.java
@@ -421,6 +421,42 @@ public class DataJdbcSource extends DataSqlSource {
}
}
+ @Override
+ protected CompletableFuture