This is an automated email from the ASF dual-hosted git repository.
mcasters pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new 886ae7e590 issue #6681 (#6682)
886ae7e590 is described below
commit 886ae7e590fb35899720c9d0ec707fbbfa5d6529
Author: Matt Casters <[email protected]>
AuthorDate: Sat Feb 28 20:53:01 2026 +0100
issue #6681 (#6682)
* issue #6681
* issue #6681 (formatting)
* issue #6681 (formatting)
* issue #6681 (missing relationships with metrics)
---
.../neo4j/execution/NeoExecutionInfoLocation.java | 61 +++++++++++++++++-----
.../neo4j/execution/builder/BaseCypherBuilder.java | 30 +++++++++++
.../execution/builder/CypherCreateBuilder.java | 2 +
.../execution/builder/CypherMergeBuilder.java | 14 +----
.../hop/neo4j/execution/path/PathResult.java | 2 +-
.../path/base/NeoExecutionViewerTabBase.java | 2 +-
.../hop/neo4j/perspective/HistoryResult.java | 2 +-
7 files changed, 83 insertions(+), 30 deletions(-)
diff --git
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/NeoExecutionInfoLocation.java
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/NeoExecutionInfoLocation.java
index 2ec2117b99..ce0d54dfe1 100644
---
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/NeoExecutionInfoLocation.java
+++
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/NeoExecutionInfoLocation.java
@@ -21,6 +21,9 @@ package org.apache.hop.neo4j.execution;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
@@ -44,6 +47,7 @@ import org.apache.hop.core.row.IValueMeta;
import org.apache.hop.core.row.JsonRowMeta;
import org.apache.hop.core.row.RowBuffer;
import org.apache.hop.core.row.RowMeta;
+import org.apache.hop.core.row.value.ValueMetaJson;
import org.apache.hop.core.variables.IVariables;
import org.apache.hop.execution.Execution;
import org.apache.hop.execution.ExecutionBuilder;
@@ -156,6 +160,7 @@ public class NeoExecutionInfoLocation implements
IExecutionInfoLocation {
public static final String R_HAS_METADATA = "HAS_METADATA";
public static final String R_HAS_DATASET = "HAS_DATASET";
public static final String R_HAS_ROW = "HAS_ROW";
+ public static final String R_HAS_METRIC = "HAS_METRIC";
public static final String CONST_ERROR_GETTING_EXECUTION_FROM_NEO_4_J =
"Error getting execution from Neo4j";
@@ -639,13 +644,13 @@ public class NeoExecutionInfoLocation implements
IExecutionInfoLocation {
.withLabelAndKey(EL_EXECUTION, EP_ID, state.getId())
.withValue(EP_STATUS_DESCRIPTION, state.getStatusDescription())
.withValue(EP_LOGGING_TEXT, state.getLoggingText())
+ .withValue(EP_EXECUTION_TYPE, state.getExecutionType().name())
.withValue(EP_UPDATE_TIME, state.getUpdateTime())
.withValue(EP_CHILD_IDS, state.getChildIds())
.withValue(EP_FAILED, state.isFailed())
.withValue(EP_DETAILS, state.getDetails())
.withValue(EP_CONTAINER_ID, state.getContainerId())
.withValue(EP_EXECUTION_END_DATE, state.getExecutionEndDate());
-
transaction.run(stateCypherBuilder.cypher(),
stateCypherBuilder.parameters());
// Save the metrics as well...
@@ -655,17 +660,23 @@ public class NeoExecutionInfoLocation implements
IExecutionInfoLocation {
// Save all the metrics in this map in there...
//
for (String metricKey : metric.getMetrics().keySet()) {
+ Map<String, Object> metricKeys =
+ Map.of(
+ CP_ID, state.getId(),
+ CP_NAME, metric.getComponentName(),
+ CP_COPY_NR, metric.getComponentCopy(),
+ CP_METRIC_KEY, metricKey);
CypherCreateBuilder metricBuilder =
CypherCreateBuilder.of()
- .withLabelAndKeys(
- CL_EXECUTION_METRIC,
- Map.of(
- CP_ID, state.getId(),
- CP_NAME, metric.getComponentName(),
- CP_COPY_NR, metric.getComponentCopy(),
- CP_METRIC_KEY, metricKey))
+ .withLabelAndKeys(CL_EXECUTION_METRIC, metricKeys)
.withValue(CP_METRIC_VALUE,
metric.getMetrics().get(metricKey));
execute(transaction, metricBuilder);
+ CypherRelationshipBuilder relationshipBuilder =
+ CypherRelationshipBuilder.of()
+ .withMatch(EL_EXECUTION, "e", EP_ID, state.getId())
+ .withMatch(CL_EXECUTION_METRIC, "m", metricKeys)
+ .withCreate("e", "m", R_HAS_METRIC);
+ execute(transaction, relationshipBuilder);
}
}
}
@@ -1369,12 +1380,34 @@ public class NeoExecutionInfoLocation implements
IExecutionInfoLocation {
}
case IValueMeta.TYPE_BOOLEAN -> value.asBoolean();
case IValueMeta.TYPE_NUMBER -> value.asDouble();
- default -> {
- log.logError(
- "Data type not yet supported : "
- + valueMeta.getTypeDesc()
- + " (non-fatal, returning null)");
- yield null;
+ case IValueMeta.TYPE_BIGNUMBER -> new BigDecimal(value.asString());
+ case IValueMeta.TYPE_TIMESTAMP -> {
+ try {
+ yield Timestamp.valueOf(value.asString());
+ } catch (Exception pe) {
+ yield pe.getMessage();
+ }
+ }
+ case IValueMeta.TYPE_JSON -> {
+ // We get the String version
+ // Convert to type JsonNode
+ //
+ try {
+ yield ((ValueMetaJson)
valueMeta).convertStringToJson(value.asString());
+ } catch (Exception e) {
+ yield e.getMessage();
+ }
+ }
+ default ->
+ // Convert from String
+ //
+ {
+ try {
+ yield valueMeta.convertBinaryStringToNativeType(
+ value.asString().getBytes(StandardCharsets.UTF_8));
+ } catch (HopException ve) {
+ yield null;
+ }
}
};
}
diff --git
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/BaseCypherBuilder.java
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/BaseCypherBuilder.java
index 8d71b700fe..62969f1ff1 100644
---
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/BaseCypherBuilder.java
+++
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/BaseCypherBuilder.java
@@ -18,11 +18,17 @@
package org.apache.hop.neo4j.execution.builder;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import org.apache.hop.core.json.HopJson;
public abstract class BaseCypherBuilder implements ICypherBuilder {
protected StringBuilder cypher;
@@ -58,4 +64,28 @@ public abstract class BaseCypherBuilder implements
ICypherBuilder {
public Map<String, Object> parameters() {
return parameters;
}
+
+ public static SimpleDateFormat timestampFormat =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSSSS");
+
+ protected Object mapTypes(Object value) {
+ Object result = value;
+ if (value instanceof BigDecimal) {
+ result = value.toString();
+ }
+ if (value instanceof Timestamp) {
+ result = timestampFormat.format((Timestamp) value);
+ }
+ if (value instanceof Map) {
+ try {
+ result = HopJson.newMapper().writeValueAsString(value);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException("Error converting Map to a JSON String", e);
+ }
+ }
+ if (value instanceof JsonNode node) {
+ result = node.toPrettyString();
+ }
+ return result;
+ }
}
diff --git
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/CypherCreateBuilder.java
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/CypherCreateBuilder.java
index a844816b68..18f86492e8 100644
---
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/CypherCreateBuilder.java
+++
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/CypherCreateBuilder.java
@@ -68,6 +68,8 @@ public class CypherCreateBuilder extends BaseCypherBuilder {
}
cypher.append("n.").append(property).append("=$").append(property).append(" ");
+ value = mapTypes(value);
+
addParameter(property, value);
return this;
diff --git
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/CypherMergeBuilder.java
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/CypherMergeBuilder.java
index bb340871fd..2c0c36da86 100644
---
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/CypherMergeBuilder.java
+++
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/builder/CypherMergeBuilder.java
@@ -18,9 +18,7 @@
package org.apache.hop.neo4j.execution.builder;
-import com.fasterxml.jackson.core.JsonProcessingException;
import java.util.Map;
-import org.apache.hop.core.json.HopJson;
public class CypherMergeBuilder extends BaseCypherBuilder {
private CypherMergeBuilder() {
@@ -71,17 +69,7 @@ public class CypherMergeBuilder extends BaseCypherBuilder {
}
cypher.append("n.").append(property).append("=$").append(property).append(" ");
- if (value instanceof Map) {
- String jsonString;
- try {
- jsonString = HopJson.newMapper().writeValueAsString(value);
- } catch (JsonProcessingException e) {
- throw new RuntimeException("Error converting Map to a JSON String", e);
- }
- addParameter(property, jsonString);
- } else {
- addParameter(property, value);
- }
+ addParameter(property, mapTypes(value));
return this;
}
diff --git
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/path/PathResult.java
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/path/PathResult.java
index 268a9ee315..8cdb91ed1d 100644
---
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/path/PathResult.java
+++
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/path/PathResult.java
@@ -206,7 +206,7 @@ public class PathResult {
cmd.append(" , p=shortestpath((top)-[:EXECUTES*]-(err))
").append(Const.CR);
cmd.append("WHERE top.registrationDate IS NOT NULL ").append(Const.CR);
cmd.append(" AND err.errors > 0 ").append(Const.CR);
- cmd.append(" AND size((err)-[:EXECUTES]->())=0 ").append(Const.CR);
+ cmd.append(" AND err.id <>
'").append(getId()).append("'").append(Const.CR);
cmd.append("RETURN p ").append(Const.CR);
cmd.append("ORDER BY size(RELATIONSHIPS(p)) DESC ").append(Const.CR);
cmd.append("LIMIT 5").append(Const.CR);
diff --git
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/path/base/NeoExecutionViewerTabBase.java
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/path/base/NeoExecutionViewerTabBase.java
index d8950609e1..cc778b726f 100644
---
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/path/base/NeoExecutionViewerTabBase.java
+++
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/execution/path/base/NeoExecutionViewerTabBase.java
@@ -91,7 +91,7 @@ public abstract class NeoExecutionViewerTabBase {
+ Const.CR
+ "WHERE child.failed "
+ Const.CR
- + "AND size((child)-[:EXECUTES]->())=0 "
+ + "AND child.id <> $executionId "
+ Const.CR
+ "RETURN p "
+ Const.CR
diff --git
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/perspective/HistoryResult.java
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/perspective/HistoryResult.java
index dfe0160f0d..d819a20a65 100644
---
a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/perspective/HistoryResult.java
+++
b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/perspective/HistoryResult.java
@@ -311,7 +311,7 @@ public class HistoryResult {
cmd.append(" , p=shortestpath((top)-[:EXECUTES*]-(err))
").append(Const.CR);
cmd.append("WHERE top.registrationDate IS NOT NULL ").append(Const.CR);
cmd.append(" AND err.errors > 0 ").append(Const.CR);
- cmd.append(" AND size((err)-[:EXECUTES]->())=0 ").append(Const.CR);
+ cmd.append(" AND err.id <>
'").append(getId()).append("'").append(Const.CR);
cmd.append("RETURN p ").append(Const.CR);
cmd.append("ORDER BY size(RELATIONSHIPS(p)) DESC ").append(Const.CR);
cmd.append("LIMIT 5").append(Const.CR);