This is an automated email from the ASF dual-hosted git repository.

hansva 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 7500c68798 add variable injection support back, fixes #7265 (#7269)
7500c68798 is described below

commit 7500c68798c928be8019457f2e3cacb0c00876d3
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Thu Jun 11 12:41:17 2026 +0200

    add variable injection support back, fixes #7265 (#7269)
---
 ...ate.hpl => 0054-load-file-content-template.hpl} |   2 +-
 ...ate.hpl => 0054-load-file-content-validate.hpl} |   2 +-
 ...file-content.hpl => 0054-load-file-content.hpl} |  12 +-
 ...child.hpl => 0055-set-constant-value-child.hpl} |   2 +-
 ...rent.hpl => 0055-set-constant-value-parent.hpl} |  10 +-
 ...te.hpl => 0056-mdi-multi-datagrid-template.hpl} |   2 +-
 ...ti-datagrid.hpl => 0056-mdi-multi-datagrid.hpl} |   6 +-
 ...late.hpl => 0057-mdi-shared-field-template.hpl} |   2 +-
 ...-shared-field.hpl => 0057-mdi-shared-field.hpl} |   6 +-
 ...mplate.hpl => 0058-mdi-edge-cases-template.hpl} |   2 +-
 ...-mdi-edge-cases.hpl => 0058-mdi-edge-cases.hpl} |   6 +-
 ...ld.hpl => 0059-mdi-constant-variable-child.hpl} |  93 +++++-----
 .../mdi/0059-mdi-constant-variable-parent.hpl      | 198 +++++++++++++++++++++
 ...content.hwf => main-0054-load-file-content.hwf} |  16 +-
 ...-value.hwf => main-0055-set-constant-value.hwf} |   4 +-
 ...tagrid.hwf => main-0056-mdi-multi-datagrid.hwf} |  14 +-
 ...ed-field.hwf => main-0057-mdi-shared-field.hwf} |  14 +-
 ...edge-cases.hwf => main-0058-mdi-edge-cases.hwf} |  14 +-
 ...ent.hwf => main-0059-mdi-constant-variable.hwf} |  57 ++----
 ...n => 0054-load-file-content-validate UNIT.json} |   4 +-
 ...on => 0055-set-constant-value-parent UNIT.json} |   4 +-
 ... => 0056-mdi-multi-datagrid-template UNIT.json} |   4 +-
 ...on => 0057-mdi-shared-field-template UNIT.json} |   4 +-
 ...json => 0058-mdi-edge-cases-template UNIT.json} |   4 +-
 .../pipeline/transforms/metainject/MetaInject.java |  25 ++-
 .../transforms/metainject/MetaInjectTest.java      |  45 +++++
 26 files changed, 387 insertions(+), 165 deletions(-)

diff --git a/integration-tests/mdi/0087-load-file-content-template.hpl 
b/integration-tests/mdi/0054-load-file-content-template.hpl
similarity index 97%
rename from integration-tests/mdi/0087-load-file-content-template.hpl
rename to integration-tests/mdi/0054-load-file-content-template.hpl
index 60f93fac1c..dba68f1903 100644
--- a/integration-tests/mdi/0087-load-file-content-template.hpl
+++ b/integration-tests/mdi/0054-load-file-content-template.hpl
@@ -19,7 +19,7 @@ limitations under the License.
 -->
 <pipeline>
   <info>
-    <name>0087-load-file-content-template</name>
+    <name>0054-load-file-content-template</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description/>
     <extended_description/>
diff --git a/integration-tests/mdi/0087-load-file-content-validate.hpl 
b/integration-tests/mdi/0054-load-file-content-validate.hpl
similarity index 99%
rename from integration-tests/mdi/0087-load-file-content-validate.hpl
rename to integration-tests/mdi/0054-load-file-content-validate.hpl
index f3191b0c4b..026a240a0f 100644
--- a/integration-tests/mdi/0087-load-file-content-validate.hpl
+++ b/integration-tests/mdi/0054-load-file-content-validate.hpl
@@ -19,7 +19,7 @@ limitations under the License.
 -->
 <pipeline>
   <info>
-    <name>0087-load-file-content-validate</name>
+    <name>0054-load-file-content-validate</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description/>
     <extended_description/>
diff --git a/integration-tests/mdi/0087-load-file-content.hpl 
b/integration-tests/mdi/0054-load-file-content.hpl
similarity index 97%
rename from integration-tests/mdi/0087-load-file-content.hpl
rename to integration-tests/mdi/0054-load-file-content.hpl
index 978e4ce8ad..1198ec2573 100644
--- a/integration-tests/mdi/0087-load-file-content.hpl
+++ b/integration-tests/mdi/0054-load-file-content.hpl
@@ -19,7 +19,7 @@ limitations under the License.
 -->
 <pipeline>
   <info>
-    <name>0087-load-file-content</name>
+    <name>0054-load-file-content</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description/>
     <extended_description/>
@@ -40,22 +40,22 @@ limitations under the License.
   <order>
     <hop>
       <from>golden-load-file-content</from>
-      <to>0087-load-file-content-template.hpl</to>
+      <to>0054-load-file-content-template.hpl</to>
       <enabled>Y</enabled>
     </hop>
     <hop>
       <from>golden-load-file-content-files</from>
-      <to>0087-load-file-content-template.hpl</to>
+      <to>0054-load-file-content-template.hpl</to>
       <enabled>Y</enabled>
     </hop>
     <hop>
       <from>golden-load-file-content-fields</from>
-      <to>0087-load-file-content-template.hpl</to>
+      <to>0054-load-file-content-template.hpl</to>
       <enabled>Y</enabled>
     </hop>
   </order>
   <transform>
-    <name>0087-load-file-content-template.hpl</name>
+    <name>0054-load-file-content-template.hpl</name>
     <type>MetaInject</type>
     <description/>
     <distribute>Y</distribute>
@@ -65,7 +65,7 @@ limitations under the License.
       <method>none</method>
       <schema_name/>
     </partitioning>
-    <filename>${PROJECT_HOME}/0087-load-file-content-template.hpl</filename>
+    <filename>${PROJECT_HOME}/0054-load-file-content-template.hpl</filename>
     <run_configuration>local</run_configuration>
     <source_transform/>
     <source_output_fields>    </source_output_fields>
diff --git a/integration-tests/mdi/0088-set-constant-value-child.hpl 
b/integration-tests/mdi/0055-set-constant-value-child.hpl
similarity index 98%
copy from integration-tests/mdi/0088-set-constant-value-child.hpl
copy to integration-tests/mdi/0055-set-constant-value-child.hpl
index 298f23220e..89f76b6bb4 100644
--- a/integration-tests/mdi/0088-set-constant-value-child.hpl
+++ b/integration-tests/mdi/0055-set-constant-value-child.hpl
@@ -19,7 +19,7 @@ limitations under the License.
 -->
 <pipeline>
   <info>
-    <name>0088-set-constant-value-child</name>
+    <name>0055-set-constant-value-child</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description/>
     <extended_description/>
diff --git a/integration-tests/mdi/0088-set-constant-value-parent.hpl 
b/integration-tests/mdi/0055-set-constant-value-parent.hpl
similarity index 94%
rename from integration-tests/mdi/0088-set-constant-value-parent.hpl
rename to integration-tests/mdi/0055-set-constant-value-parent.hpl
index fa619b3fbb..031d60c6bb 100644
--- a/integration-tests/mdi/0088-set-constant-value-parent.hpl
+++ b/integration-tests/mdi/0055-set-constant-value-parent.hpl
@@ -26,7 +26,7 @@ limitations under the License.
     <pipeline_type>Normal</pipeline_type>
     <pipeline_status>0</pipeline_status>
     <parameters/>
-    <name>0088-set-constant-value-parent</name>
+    <name>0055-set-constant-value-parent</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description>Regression test for issue #7246: a constant value (a mapping 
without a source transform) must be injected into the template, even when 
another key in the same injection group is fed from a source 
transform.</description>
     <extended_description/>
@@ -37,8 +37,8 @@ limitations under the License.
   </info>
   <transform>
     <type>MetaInject</type>
-    <name>0088-set-constant-value-child.hpl</name>
-    <filename>${PROJECT_HOME}/0088-set-constant-value-child.hpl</filename>
+    <name>0055-set-constant-value-child.hpl</name>
+    <filename>${PROJECT_HOME}/0055-set-constant-value-child.hpl</filename>
     <source_transform>Output</source_transform>
     <source_output_fields>
       <source_output_field>
@@ -136,11 +136,11 @@ limitations under the License.
   <order>
     <hop>
       <from>fields</from>
-      <to>0088-set-constant-value-child.hpl</to>
+      <to>0055-set-constant-value-child.hpl</to>
       <enabled>Y</enabled>
     </hop>
     <hop>
-      <from>0088-set-constant-value-child.hpl</from>
+      <from>0055-set-constant-value-child.hpl</from>
       <to>Verify</to>
       <enabled>Y</enabled>
     </hop>
diff --git a/integration-tests/mdi/0089-mdi-multi-datagrid-template.hpl 
b/integration-tests/mdi/0056-mdi-multi-datagrid-template.hpl
similarity index 98%
rename from integration-tests/mdi/0089-mdi-multi-datagrid-template.hpl
rename to integration-tests/mdi/0056-mdi-multi-datagrid-template.hpl
index d10eafb72c..1d269179da 100644
--- a/integration-tests/mdi/0089-mdi-multi-datagrid-template.hpl
+++ b/integration-tests/mdi/0056-mdi-multi-datagrid-template.hpl
@@ -19,7 +19,7 @@ limitations under the License.
 -->
 <pipeline>
   <info>
-    <name>0089-mdi-multi-datagrid-template</name>
+    <name>0056-mdi-multi-datagrid-template</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description/>
     <extended_description/>
diff --git a/integration-tests/mdi/0089-mdi-multi-datagrid.hpl 
b/integration-tests/mdi/0056-mdi-multi-datagrid.hpl
similarity index 96%
rename from integration-tests/mdi/0089-mdi-multi-datagrid.hpl
rename to integration-tests/mdi/0056-mdi-multi-datagrid.hpl
index ee0153cd62..01c0d250ff 100644
--- a/integration-tests/mdi/0089-mdi-multi-datagrid.hpl
+++ b/integration-tests/mdi/0056-mdi-multi-datagrid.hpl
@@ -19,7 +19,7 @@ limitations under the License.
 -->
 <pipeline>
   <info>
-    <name>0089-mdi-multi-datagrid</name>
+    <name>0056-mdi-multi-datagrid</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description>Injects a single Select Values "fields" group from two 
separate data grids. Reproduces the regression where the second grid's source 
field can not be found because the group row layout is cached from the first 
grid only.</description>
     <extended_description/>
@@ -60,11 +60,11 @@ limitations under the License.
       <method>none</method>
       <schema_name/>
     </partitioning>
-    <filename>${PROJECT_HOME}/0089-mdi-multi-datagrid-template.hpl</filename>
+    <filename>${PROJECT_HOME}/0056-mdi-multi-datagrid-template.hpl</filename>
     <run_configuration>local</run_configuration>
     <source_transform/>
     <source_output_fields>    </source_output_fields>
-    
<target_file>${PROJECT_HOME}/0089-mdi-multi-datagrid-template-injected.hpl</target_file>
+    
<target_file>${PROJECT_HOME}/0056-mdi-multi-datagrid-template-injected.hpl</target_file>
     <create_parent_folder>Y</create_parent_folder>
     <no_execution>N</no_execution>
     <stream_source_transform/>
diff --git a/integration-tests/mdi/0090-mdi-shared-field-template.hpl 
b/integration-tests/mdi/0057-mdi-shared-field-template.hpl
similarity index 98%
rename from integration-tests/mdi/0090-mdi-shared-field-template.hpl
rename to integration-tests/mdi/0057-mdi-shared-field-template.hpl
index 5894c4795e..3ae0e32101 100644
--- a/integration-tests/mdi/0090-mdi-shared-field-template.hpl
+++ b/integration-tests/mdi/0057-mdi-shared-field-template.hpl
@@ -19,7 +19,7 @@ limitations under the License.
 -->
 <pipeline>
   <info>
-    <name>0090-mdi-shared-field-template</name>
+    <name>0057-mdi-shared-field-template</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description/>
     <extended_description/>
diff --git a/integration-tests/mdi/0090-mdi-shared-field.hpl 
b/integration-tests/mdi/0057-mdi-shared-field.hpl
similarity index 96%
rename from integration-tests/mdi/0090-mdi-shared-field.hpl
rename to integration-tests/mdi/0057-mdi-shared-field.hpl
index e92f7531ed..50f69b2c5d 100644
--- a/integration-tests/mdi/0090-mdi-shared-field.hpl
+++ b/integration-tests/mdi/0057-mdi-shared-field.hpl
@@ -19,7 +19,7 @@ limitations under the License.
 -->
 <pipeline>
   <info>
-    <name>0090-mdi-shared-field</name>
+    <name>0057-mdi-shared-field</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description>Injects one and the same source field into several injection 
targets: two keys (FIELD_NAME and FIELD_RENAME) of one Select Values group and 
the FIELD_NAME key of a second Select Values transform. Verifies that reusing a 
single input column for multiple injection transforms/groups 
works.</description>
     <extended_description/>
@@ -55,11 +55,11 @@ limitations under the License.
       <method>none</method>
       <schema_name/>
     </partitioning>
-    <filename>${PROJECT_HOME}/0090-mdi-shared-field-template.hpl</filename>
+    <filename>${PROJECT_HOME}/0057-mdi-shared-field-template.hpl</filename>
     <run_configuration>local</run_configuration>
     <source_transform/>
     <source_output_fields>    </source_output_fields>
-    
<target_file>${PROJECT_HOME}/0090-mdi-shared-field-template-injected.hpl</target_file>
+    
<target_file>${PROJECT_HOME}/0057-mdi-shared-field-template-injected.hpl</target_file>
     <create_parent_folder>Y</create_parent_folder>
     <no_execution>N</no_execution>
     <stream_source_transform/>
diff --git a/integration-tests/mdi/0091-mdi-edge-cases-template.hpl 
b/integration-tests/mdi/0058-mdi-edge-cases-template.hpl
similarity index 98%
rename from integration-tests/mdi/0091-mdi-edge-cases-template.hpl
rename to integration-tests/mdi/0058-mdi-edge-cases-template.hpl
index a4e0679ac6..cdef004713 100644
--- a/integration-tests/mdi/0091-mdi-edge-cases-template.hpl
+++ b/integration-tests/mdi/0058-mdi-edge-cases-template.hpl
@@ -19,7 +19,7 @@ limitations under the License.
 -->
 <pipeline>
   <info>
-    <name>0091-mdi-edge-cases-template</name>
+    <name>0058-mdi-edge-cases-template</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description/>
     <extended_description/>
diff --git a/integration-tests/mdi/0091-mdi-edge-cases.hpl 
b/integration-tests/mdi/0058-mdi-edge-cases.hpl
similarity index 97%
rename from integration-tests/mdi/0091-mdi-edge-cases.hpl
rename to integration-tests/mdi/0058-mdi-edge-cases.hpl
index 53cb679e1f..7cae61197d 100644
--- a/integration-tests/mdi/0091-mdi-edge-cases.hpl
+++ b/integration-tests/mdi/0058-mdi-edge-cases.hpl
@@ -26,7 +26,7 @@ limitations under the License.
     <pipeline_type>Normal</pipeline_type>
     <pipeline_status>0</pipeline_status>
     <parameters/>
-    <name>0091-mdi-edge-cases</name>
+    <name>0058-mdi-edge-cases</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
     <description>Stress test for metadata injection group handling. The Select 
Values METAS group is fed from two source transforms with a different number of 
rows (select fields = 4 rows, renames = 2 rows), mixed with a constant 
(META_TYPE), while the 'select fields' grid is reused across two different 
groups (FIELDS via FIELD_NAME and METAS via META_NAME).</description>
     <extended_description/>
@@ -38,7 +38,7 @@ limitations under the License.
   <transform>
     <type>MetaInject</type>
     <name>ETL metadata injection</name>
-    <filename>${PROJECT_HOME}/0091-mdi-edge-cases-template.hpl</filename>
+    <filename>${PROJECT_HOME}/0058-mdi-edge-cases-template.hpl</filename>
     <source_transform/>
     <source_output_fields/>
     <mappings>
@@ -70,7 +70,7 @@ limitations under the License.
         <target_detail>Y</target_detail>
       </mapping>
     </mappings>
-    
<target_file>${PROJECT_HOME}/0091-mdi-edge-cases-template-injected.hpl</target_file>
+    
<target_file>${PROJECT_HOME}/0058-mdi-edge-cases-template-injected.hpl</target_file>
     <no_execution>N</no_execution>
     <allow_empty_stream_on_execution>N</allow_empty_stream_on_execution>
     <stream_source_transform/>
diff --git a/integration-tests/mdi/0088-set-constant-value-child.hpl 
b/integration-tests/mdi/0059-mdi-constant-variable-child.hpl
similarity index 66%
rename from integration-tests/mdi/0088-set-constant-value-child.hpl
rename to integration-tests/mdi/0059-mdi-constant-variable-child.hpl
index 298f23220e..03313e2ce3 100644
--- a/integration-tests/mdi/0088-set-constant-value-child.hpl
+++ b/integration-tests/mdi/0059-mdi-constant-variable-child.hpl
@@ -19,39 +19,28 @@ limitations under the License.
 -->
 <pipeline>
   <info>
-    <name>0088-set-constant-value-child</name>
+    <name>0059-mdi-constant-variable-child</name>
     <name_sync_with_filename>Y</name_sync_with_filename>
-    <description/>
-    <extended_description/>
-    <pipeline_version/>
+    <description>Template: the "Add constant" value is injected by the parent 
as a constant containing a variable</description>
     <pipeline_type>Normal</pipeline_type>
     <parameters>
     </parameters>
-    <capture_transform_performance>N</capture_transform_performance>
-    
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
-    
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
-    <created_user>-</created_user>
-    <created_date>2026/06/09 10:00:00.000</created_date>
-    <modified_user>-</modified_user>
-    <modified_date>2026/06/09 10:00:00.000</modified_date>
   </info>
-  <notepads>
-  </notepads>
   <order>
     <hop>
-      <from>Sample data</from>
-      <to>Set field value to a constant</to>
+      <from>seed</from>
+      <to>Add constant</to>
       <enabled>Y</enabled>
     </hop>
     <hop>
-      <from>Set field value to a constant</from>
-      <to>Output</to>
+      <from>Add constant</from>
+      <to>out</to>
       <enabled>Y</enabled>
     </hop>
   </order>
   <transform>
-    <name>Output</name>
-    <type>Dummy</type>
+    <name>seed</name>
+    <type>DataGrid</type>
     <description/>
     <distribute>Y</distribute>
     <custom_distribution/>
@@ -60,15 +49,29 @@ limitations under the License.
       <method>none</method>
       <schema_name/>
     </partitioning>
+    <data>
+      <line>
+        <item>x</item>
+      </line>
+    </data>
+    <fields>
+      <field>
+        <length>-1</length>
+        <precision>-1</precision>
+        <set_empty_string>N</set_empty_string>
+        <name>seed</name>
+        <type>String</type>
+      </field>
+    </fields>
     <attributes/>
     <GUI>
-      <xloc>480</xloc>
-      <yloc>112</yloc>
+      <xloc>144</xloc>
+      <yloc>96</yloc>
     </GUI>
   </transform>
   <transform>
-    <name>Set field value to a constant</name>
-    <type>SetValueConstant</type>
+    <name>Add constant</name>
+    <type>Constant</type>
     <description/>
     <distribute>Y</distribute>
     <custom_distribution/>
@@ -78,17 +81,28 @@ limitations under the License.
       <schema_name/>
     </partitioning>
     <fields>
-</fields>
-    <usevar>N</usevar>
+      <field>
+        <name>injected</name>
+        <type>String</type>
+        <format/>
+        <currency/>
+        <decimal/>
+        <group/>
+        <nullif>PLACEHOLDER</nullif>
+        <length>-1</length>
+        <precision>-1</precision>
+        <set_empty_string>N</set_empty_string>
+      </field>
+    </fields>
     <attributes/>
     <GUI>
-      <xloc>320</xloc>
-      <yloc>112</yloc>
+      <xloc>336</xloc>
+      <yloc>96</yloc>
     </GUI>
   </transform>
   <transform>
-    <name>Sample data</name>
-    <type>DataGrid</type>
+    <name>out</name>
+    <type>Dummy</type>
     <description/>
     <distribute>Y</distribute>
     <custom_distribution/>
@@ -97,27 +111,10 @@ limitations under the License.
       <method>none</method>
       <schema_name/>
     </partitioning>
-    <data>
-      <line>
-        <item>original</item>
-      </line>
-      <line>
-        <item>untouched</item>
-      </line>
-    </data>
-    <fields>
-      <field>
-        <length>-1</length>
-        <precision>-1</precision>
-        <set_empty_string>N</set_empty_string>
-        <name>x</name>
-        <type>String</type>
-      </field>
-    </fields>
     <attributes/>
     <GUI>
-      <xloc>160</xloc>
-      <yloc>112</yloc>
+      <xloc>528</xloc>
+      <yloc>96</yloc>
     </GUI>
   </transform>
   <transform_error_handling>
diff --git a/integration-tests/mdi/0059-mdi-constant-variable-parent.hpl 
b/integration-tests/mdi/0059-mdi-constant-variable-parent.hpl
new file mode 100644
index 0000000000..820dfdfc0e
--- /dev/null
+++ b/integration-tests/mdi/0059-mdi-constant-variable-parent.hpl
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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.
+
+-->
+<pipeline>
+  <info>
+    <pipeline_version/>
+    <capture_transform_performance>N</capture_transform_performance>
+    
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+    
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+    <pipeline_type>Normal</pipeline_type>
+    <pipeline_status>0</pipeline_status>
+    <parameters>
+      <parameter>
+        <name>SAMPLE</name>
+        <description/>
+        <default_value>sampleValue</default_value>
+      </parameter>
+    </parameters>
+    <name>0059-mdi-constant-variable-parent</name>
+    <name_sync_with_filename>Y</name_sync_with_filename>
+    <description>Injects a constant value containing the ${SAMPLE} variable 
into a @HopMetadataProperty template (Add constant) and verifies the variable 
is resolved</description>
+    <extended_description/>
+    <created_user>-</created_user>
+    <modified_user>-</modified_user>
+    <created_date>2026/06/11 11:20:36.014</created_date>
+    <modified_date>2026/06/11 11:20:36.014</modified_date>
+  </info>
+  <transform>
+    <type>MetaInject</type>
+    <name>ETL metadata injection</name>
+    <filename>${PROJECT_HOME}/0059-mdi-constant-variable-child.hpl</filename>
+    <source_transform>out</source_transform>
+    <source_output_fields>
+      <source_output_field>
+        <source_output_field_name>seed</source_output_field_name>
+        <source_output_field_type>String</source_output_field_type>
+        <source_output_field_length>-1</source_output_field_length>
+        <source_output_field_precision>-1</source_output_field_precision>
+      </source_output_field>
+      <source_output_field>
+        <source_output_field_name>injected</source_output_field_name>
+        <source_output_field_type>String</source_output_field_type>
+        <source_output_field_length>-1</source_output_field_length>
+        <source_output_field_precision>-1</source_output_field_precision>
+      </source_output_field>
+    </source_output_fields>
+    <mappings>
+      <mapping>
+        <source_transform/>
+        <source_field>injected</source_field>
+        <target_transform_name>Add constant</target_transform_name>
+        <target_attribute_key>name</target_attribute_key>
+        <target_detail>Y</target_detail>
+      </mapping>
+      <mapping>
+        <source_transform/>
+        <source_field>String</source_field>
+        <target_transform_name>Add constant</target_transform_name>
+        <target_attribute_key>type</target_attribute_key>
+        <target_detail>Y</target_detail>
+      </mapping>
+      <mapping>
+        <source_field>${SAMPLE}</source_field>
+        <target_transform_name>Add constant</target_transform_name>
+        <target_attribute_key>nullif</target_attribute_key>
+        <target_detail>Y</target_detail>
+      </mapping>
+    </mappings>
+    <target_file/>
+    <no_execution>N</no_execution>
+    <allow_empty_stream_on_execution>N</allow_empty_stream_on_execution>
+    <stream_source_transform/>
+    <stream_target_transform/>
+    <run_configuration>local</run_configuration>
+    <create_parent_folder>Y</create_parent_folder>
+    <distribute>Y</distribute>
+    <copies>1</copies>
+    <GUI>
+      <xloc>144</xloc>
+      <yloc>112</yloc>
+    </GUI>
+    <description/>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <attributes/>
+  </transform>
+  <transform>
+    <type>FilterRows</type>
+    <name>Check resolved</name>
+    <compare>
+      <condition>
+        <negated>N</negated>
+        <operator>-</operator>
+        <leftvalue>injected</leftvalue>
+        <function>=</function>
+        <rightvalue/>
+        <value>
+          <name>constant</name>
+          <type>String</type>
+          <text>sampleValue</text>
+          <length>-1</length>
+          <precision>-1</precision>
+          <isnull>N</isnull>
+          <mask/>
+        </value>
+        <conditions/>
+      </condition>
+    </compare>
+    <send_true_to>Resolved OK</send_true_to>
+    <send_false_to>Variable not resolved - Abort</send_false_to>
+    <distribute>Y</distribute>
+    <copies>1</copies>
+    <GUI>
+      <xloc>352</xloc>
+      <yloc>112</yloc>
+    </GUI>
+    <description/>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <attributes/>
+  </transform>
+  <transform>
+    <type>Abort</type>
+    <name>Variable not resolved - Abort</name>
+    <row_threshold>0</row_threshold>
+    <message>The ${SAMPLE} variable in the injected constant was not 
resolved</message>
+    <always_log_rows>Y</always_log_rows>
+    <abort_option>ABORT_WITH_ERROR</abort_option>
+    <distribute>Y</distribute>
+    <copies>1</copies>
+    <GUI>
+      <xloc>352</xloc>
+      <yloc>256</yloc>
+    </GUI>
+    <description/>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <attributes/>
+  </transform>
+  <transform>
+    <type>Dummy</type>
+    <name>Resolved OK</name>
+    <distribute>Y</distribute>
+    <copies>1</copies>
+    <GUI>
+      <xloc>560</xloc>
+      <yloc>112</yloc>
+    </GUI>
+    <description/>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <attributes/>
+  </transform>
+  <order>
+    <hop>
+      <from>ETL metadata injection</from>
+      <to>Check resolved</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>Check resolved</from>
+      <to>Resolved OK</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>Check resolved</from>
+      <to>Variable not resolved - Abort</to>
+      <enabled>Y</enabled>
+    </hop>
+  </order>
+  <notepads/>
+  <attributes/>
+  <transform_error_handling/>
+</pipeline>
diff --git a/integration-tests/mdi/main-0087-load-file-content.hwf 
b/integration-tests/mdi/main-0054-load-file-content.hwf
similarity index 88%
copy from integration-tests/mdi/main-0087-load-file-content.hwf
copy to integration-tests/mdi/main-0054-load-file-content.hwf
index ee4726a41f..3139aa0349 100644
--- a/integration-tests/mdi/main-0087-load-file-content.hwf
+++ b/integration-tests/mdi/main-0054-load-file-content.hwf
@@ -18,7 +18,7 @@ limitations under the License.
 
 -->
 <workflow>
-  <name>main-0087-load-file-content</name>
+  <name>main-0054-load-file-content</name>
   <name_sync_with_filename>Y</name_sync_with_filename>
   <description/>
   <extended_description/>
@@ -50,7 +50,7 @@ limitations under the License.
       <attributes_hac/>
     </action>
     <action>
-      <name>0087-load-file-content.hpl</name>
+      <name>0054-load-file-content.hpl</name>
       <description/>
       <type>PIPELINE</type>
       <attributes/>
@@ -60,7 +60,7 @@ limitations under the License.
       <clear_rows>N</clear_rows>
       <create_parent_folder>N</create_parent_folder>
       <exec_per_row>N</exec_per_row>
-      <filename>${PROJECT_HOME}/0087-load-file-content.hpl</filename>
+      <filename>${PROJECT_HOME}/0054-load-file-content.hpl</filename>
       <logext/>
       <logfile/>
       <loglevel>Basic</loglevel>
@@ -78,13 +78,13 @@ limitations under the License.
       <attributes_hac/>
     </action>
     <action>
-      <name>0087-load-file-content-validate UNIT</name>
+      <name>0054-load-file-content-validate UNIT</name>
       <description/>
       <type>RunPipelineTests</type>
       <attributes/>
       <test_names>
         <test_name>
-          <name>0087-load-file-content-validate UNIT</name>
+          <name>0054-load-file-content-validate UNIT</name>
         </test_name>
       </test_names>
       <parallel>N</parallel>
@@ -96,14 +96,14 @@ limitations under the License.
   <hops>
     <hop>
       <from>Start</from>
-      <to>0087-load-file-content.hpl</to>
+      <to>0054-load-file-content.hpl</to>
       <enabled>Y</enabled>
       <evaluation>Y</evaluation>
       <unconditional>Y</unconditional>
     </hop>
     <hop>
-      <from>0087-load-file-content.hpl</from>
-      <to>0087-load-file-content-validate UNIT</to>
+      <from>0054-load-file-content.hpl</from>
+      <to>0054-load-file-content-validate UNIT</to>
       <enabled>Y</enabled>
       <evaluation>Y</evaluation>
       <unconditional>N</unconditional>
diff --git a/integration-tests/mdi/main-0088-set-constant-value.hwf 
b/integration-tests/mdi/main-0055-set-constant-value.hwf
similarity index 95%
rename from integration-tests/mdi/main-0088-set-constant-value.hwf
rename to integration-tests/mdi/main-0055-set-constant-value.hwf
index 602ca5c15e..ad56f99a83 100644
--- a/integration-tests/mdi/main-0088-set-constant-value.hwf
+++ b/integration-tests/mdi/main-0055-set-constant-value.hwf
@@ -18,7 +18,7 @@ limitations under the License.
 
 -->
 <workflow>
-  <name>main-0088-set-constant-value</name>
+  <name>main-0055-set-constant-value</name>
   <name_sync_with_filename>Y</name_sync_with_filename>
   <description/>
   <extended_description/>
@@ -55,7 +55,7 @@ limitations under the License.
       <attributes/>
       <test_names>
         <test_name>
-          <name>0088-set-constant-value-parent UNIT</name>
+          <name>0055-set-constant-value-parent UNIT</name>
         </test_name>
       </test_names>
       <parallel>N</parallel>
diff --git a/integration-tests/mdi/main-0089-mdi-multi-datagrid.hwf 
b/integration-tests/mdi/main-0056-mdi-multi-datagrid.hwf
similarity index 90%
rename from integration-tests/mdi/main-0089-mdi-multi-datagrid.hwf
rename to integration-tests/mdi/main-0056-mdi-multi-datagrid.hwf
index d040b6dd49..0f26366bf0 100644
--- a/integration-tests/mdi/main-0089-mdi-multi-datagrid.hwf
+++ b/integration-tests/mdi/main-0056-mdi-multi-datagrid.hwf
@@ -18,7 +18,7 @@ limitations under the License.
 
 -->
 <workflow>
-  <name>main-0089-mdi-multi-datagrid</name>
+  <name>main-0056-mdi-multi-datagrid</name>
   <name_sync_with_filename>Y</name_sync_with_filename>
   <description/>
   <extended_description/>
@@ -49,7 +49,7 @@ limitations under the License.
       <attributes_hac/>
     </action>
     <action>
-      <name>0089-mdi-multi-datagrid.hpl</name>
+      <name>0056-mdi-multi-datagrid.hpl</name>
       <description/>
       <type>PIPELINE</type>
       <attributes/>
@@ -59,7 +59,7 @@ limitations under the License.
       <clear_rows>N</clear_rows>
       <create_parent_folder>N</create_parent_folder>
       <exec_per_row>N</exec_per_row>
-      <filename>${PROJECT_HOME}/0089-mdi-multi-datagrid.hpl</filename>
+      <filename>${PROJECT_HOME}/0056-mdi-multi-datagrid.hpl</filename>
       <loglevel>Basic</loglevel>
       <parameters>
         <pass_all_parameters>Y</pass_all_parameters>
@@ -81,7 +81,7 @@ limitations under the License.
       <attributes/>
       <test_names>
         <test_name>
-          <name>0089-mdi-multi-datagrid-template UNIT</name>
+          <name>0056-mdi-multi-datagrid-template UNIT</name>
         </test_name>
       </test_names>
       <parallel>N</parallel>
@@ -95,7 +95,7 @@ limitations under the License.
       <type>DELETE_FILE</type>
       <attributes/>
       <fail_if_file_not_exists>N</fail_if_file_not_exists>
-      
<filename>${PROJECT_HOME}/0089-mdi-multi-datagrid-template-injected.hpl</filename>
+      
<filename>${PROJECT_HOME}/0056-mdi-multi-datagrid-template-injected.hpl</filename>
       <parallel>N</parallel>
       <xloc>464</xloc>
       <yloc>272</yloc>
@@ -105,13 +105,13 @@ limitations under the License.
   <hops>
     <hop>
       <from>Start</from>
-      <to>0089-mdi-multi-datagrid.hpl</to>
+      <to>0056-mdi-multi-datagrid.hpl</to>
       <enabled>Y</enabled>
       <evaluation>Y</evaluation>
       <unconditional>Y</unconditional>
     </hop>
     <hop>
-      <from>0089-mdi-multi-datagrid.hpl</from>
+      <from>0056-mdi-multi-datagrid.hpl</from>
       <to>Run Pipeline Unit Tests</to>
       <enabled>Y</enabled>
       <evaluation>Y</evaluation>
diff --git a/integration-tests/mdi/main-0090-mdi-shared-field.hwf 
b/integration-tests/mdi/main-0057-mdi-shared-field.hwf
similarity index 91%
rename from integration-tests/mdi/main-0090-mdi-shared-field.hwf
rename to integration-tests/mdi/main-0057-mdi-shared-field.hwf
index 0de808ab38..5fb9b43b20 100644
--- a/integration-tests/mdi/main-0090-mdi-shared-field.hwf
+++ b/integration-tests/mdi/main-0057-mdi-shared-field.hwf
@@ -18,7 +18,7 @@ limitations under the License.
 
 -->
 <workflow>
-  <name>main-0090-mdi-shared-field</name>
+  <name>main-0057-mdi-shared-field</name>
   <name_sync_with_filename>Y</name_sync_with_filename>
   <description/>
   <extended_description/>
@@ -49,7 +49,7 @@ limitations under the License.
       <attributes_hac/>
     </action>
     <action>
-      <name>0090-mdi-shared-field.hpl</name>
+      <name>0057-mdi-shared-field.hpl</name>
       <description/>
       <type>PIPELINE</type>
       <attributes/>
@@ -59,7 +59,7 @@ limitations under the License.
       <clear_rows>N</clear_rows>
       <create_parent_folder>N</create_parent_folder>
       <exec_per_row>N</exec_per_row>
-      <filename>${PROJECT_HOME}/0090-mdi-shared-field.hpl</filename>
+      <filename>${PROJECT_HOME}/0057-mdi-shared-field.hpl</filename>
       <loglevel>Basic</loglevel>
       <parameters>
         <pass_all_parameters>Y</pass_all_parameters>
@@ -81,7 +81,7 @@ limitations under the License.
       <attributes/>
       <test_names>
         <test_name>
-          <name>0090-mdi-shared-field-template UNIT</name>
+          <name>0057-mdi-shared-field-template UNIT</name>
         </test_name>
       </test_names>
       <parallel>N</parallel>
@@ -95,7 +95,7 @@ limitations under the License.
       <type>DELETE_FILE</type>
       <attributes/>
       <fail_if_file_not_exists>N</fail_if_file_not_exists>
-      
<filename>${PROJECT_HOME}/0090-mdi-shared-field-template-injected.hpl</filename>
+      
<filename>${PROJECT_HOME}/0057-mdi-shared-field-template-injected.hpl</filename>
       <parallel>N</parallel>
       <xloc>464</xloc>
       <yloc>272</yloc>
@@ -105,13 +105,13 @@ limitations under the License.
   <hops>
     <hop>
       <from>Start</from>
-      <to>0090-mdi-shared-field.hpl</to>
+      <to>0057-mdi-shared-field.hpl</to>
       <enabled>Y</enabled>
       <evaluation>Y</evaluation>
       <unconditional>Y</unconditional>
     </hop>
     <hop>
-      <from>0090-mdi-shared-field.hpl</from>
+      <from>0057-mdi-shared-field.hpl</from>
       <to>Run Pipeline Unit Tests</to>
       <enabled>Y</enabled>
       <evaluation>Y</evaluation>
diff --git a/integration-tests/mdi/main-0091-mdi-edge-cases.hwf 
b/integration-tests/mdi/main-0058-mdi-edge-cases.hwf
similarity index 91%
rename from integration-tests/mdi/main-0091-mdi-edge-cases.hwf
rename to integration-tests/mdi/main-0058-mdi-edge-cases.hwf
index 84f3cf408d..1232111bf6 100644
--- a/integration-tests/mdi/main-0091-mdi-edge-cases.hwf
+++ b/integration-tests/mdi/main-0058-mdi-edge-cases.hwf
@@ -18,7 +18,7 @@ limitations under the License.
 
 -->
 <workflow>
-  <name>main-0091-mdi-edge-cases</name>
+  <name>main-0058-mdi-edge-cases</name>
   <name_sync_with_filename>Y</name_sync_with_filename>
   <description/>
   <extended_description/>
@@ -49,7 +49,7 @@ limitations under the License.
       <attributes_hac/>
     </action>
     <action>
-      <name>0091-mdi-edge-cases.hpl</name>
+      <name>0058-mdi-edge-cases.hpl</name>
       <description/>
       <type>PIPELINE</type>
       <attributes/>
@@ -59,7 +59,7 @@ limitations under the License.
       <clear_rows>N</clear_rows>
       <create_parent_folder>N</create_parent_folder>
       <exec_per_row>N</exec_per_row>
-      <filename>${PROJECT_HOME}/0091-mdi-edge-cases.hpl</filename>
+      <filename>${PROJECT_HOME}/0058-mdi-edge-cases.hpl</filename>
       <loglevel>Basic</loglevel>
       <parameters>
         <pass_all_parameters>Y</pass_all_parameters>
@@ -81,7 +81,7 @@ limitations under the License.
       <attributes/>
       <test_names>
         <test_name>
-          <name>0091-mdi-edge-cases-template UNIT</name>
+          <name>0058-mdi-edge-cases-template UNIT</name>
         </test_name>
       </test_names>
       <parallel>N</parallel>
@@ -95,7 +95,7 @@ limitations under the License.
       <type>DELETE_FILE</type>
       <attributes/>
       <fail_if_file_not_exists>N</fail_if_file_not_exists>
-      
<filename>${PROJECT_HOME}/0091-mdi-edge-cases-template-injected.hpl</filename>
+      
<filename>${PROJECT_HOME}/0058-mdi-edge-cases-template-injected.hpl</filename>
       <parallel>N</parallel>
       <xloc>464</xloc>
       <yloc>272</yloc>
@@ -105,13 +105,13 @@ limitations under the License.
   <hops>
     <hop>
       <from>Start</from>
-      <to>0091-mdi-edge-cases.hpl</to>
+      <to>0058-mdi-edge-cases.hpl</to>
       <enabled>Y</enabled>
       <evaluation>Y</evaluation>
       <unconditional>Y</unconditional>
     </hop>
     <hop>
-      <from>0091-mdi-edge-cases.hpl</from>
+      <from>0058-mdi-edge-cases.hpl</from>
       <to>Run Pipeline Unit Tests</to>
       <enabled>Y</enabled>
       <evaluation>Y</evaluation>
diff --git a/integration-tests/mdi/main-0087-load-file-content.hwf 
b/integration-tests/mdi/main-0059-mdi-constant-variable.hwf
similarity index 67%
rename from integration-tests/mdi/main-0087-load-file-content.hwf
rename to integration-tests/mdi/main-0059-mdi-constant-variable.hwf
index ee4726a41f..910ae44e55 100644
--- a/integration-tests/mdi/main-0087-load-file-content.hwf
+++ b/integration-tests/mdi/main-0059-mdi-constant-variable.hwf
@@ -18,15 +18,13 @@ limitations under the License.
 
 -->
 <workflow>
-  <name>main-0087-load-file-content</name>
+  <name>main-0059-mdi-constant-variable</name>
   <name_sync_with_filename>Y</name_sync_with_filename>
   <description/>
-  <extended_description/>
-  <workflow_version/>
   <created_user>-</created_user>
-  <created_date>2026/03/19 09:54:45.798</created_date>
+  <created_date>2026/06/11 12:00:00.000</created_date>
   <modified_user>-</modified_user>
-  <modified_date>2026/03/19 09:54:45.798</modified_date>
+  <modified_date>2026/06/11 12:00:00.000</modified_date>
   <parameters>
     </parameters>
   <actions>
@@ -35,22 +33,21 @@ limitations under the License.
       <description/>
       <type>SPECIAL</type>
       <attributes/>
-      <DayOfMonth>1</DayOfMonth>
-      <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
-      <hour>12</hour>
-      <intervalMinutes>60</intervalMinutes>
-      <intervalSeconds>0</intervalSeconds>
-      <minutes>0</minutes>
       <repeat>N</repeat>
       <schedulerType>0</schedulerType>
+      <intervalSeconds>0</intervalSeconds>
+      <intervalMinutes>60</intervalMinutes>
+      <hour>12</hour>
+      <minutes>0</minutes>
       <weekDay>1</weekDay>
+      <DayOfMonth>1</DayOfMonth>
       <parallel>N</parallel>
-      <xloc>96</xloc>
-      <yloc>64</yloc>
+      <xloc>128</xloc>
+      <yloc>112</yloc>
       <attributes_hac/>
     </action>
     <action>
-      <name>0087-load-file-content.hpl</name>
+      <name>0059-mdi-constant-variable-parent.hpl</name>
       <description/>
       <type>PIPELINE</type>
       <attributes/>
@@ -60,9 +57,7 @@ limitations under the License.
       <clear_rows>N</clear_rows>
       <create_parent_folder>N</create_parent_folder>
       <exec_per_row>N</exec_per_row>
-      <filename>${PROJECT_HOME}/0087-load-file-content.hpl</filename>
-      <logext/>
-      <logfile/>
+      
<filename>${PROJECT_HOME}/0059-mdi-constant-variable-parent.hpl</filename>
       <loglevel>Basic</loglevel>
       <parameters>
         <pass_all_parameters>Y</pass_all_parameters>
@@ -73,41 +68,19 @@ limitations under the License.
       <set_logfile>N</set_logfile>
       <wait_until_finished>Y</wait_until_finished>
       <parallel>N</parallel>
-      <xloc>256</xloc>
-      <yloc>64</yloc>
-      <attributes_hac/>
-    </action>
-    <action>
-      <name>0087-load-file-content-validate UNIT</name>
-      <description/>
-      <type>RunPipelineTests</type>
-      <attributes/>
-      <test_names>
-        <test_name>
-          <name>0087-load-file-content-validate UNIT</name>
-        </test_name>
-      </test_names>
-      <parallel>N</parallel>
-      <xloc>480</xloc>
-      <yloc>64</yloc>
+      <xloc>320</xloc>
+      <yloc>112</yloc>
       <attributes_hac/>
     </action>
   </actions>
   <hops>
     <hop>
       <from>Start</from>
-      <to>0087-load-file-content.hpl</to>
+      <to>0059-mdi-constant-variable-parent.hpl</to>
       <enabled>Y</enabled>
       <evaluation>Y</evaluation>
       <unconditional>Y</unconditional>
     </hop>
-    <hop>
-      <from>0087-load-file-content.hpl</from>
-      <to>0087-load-file-content-validate UNIT</to>
-      <enabled>Y</enabled>
-      <evaluation>Y</evaluation>
-      <unconditional>N</unconditional>
-    </hop>
   </hops>
   <notepads>
   </notepads>
diff --git 
a/integration-tests/mdi/metadata/unit-test/0087-load-file-content-validate 
UNIT.json 
b/integration-tests/mdi/metadata/unit-test/0054-load-file-content-validate 
UNIT.json
similarity index 97%
rename from 
integration-tests/mdi/metadata/unit-test/0087-load-file-content-validate 
UNIT.json
rename to 
integration-tests/mdi/metadata/unit-test/0054-load-file-content-validate 
UNIT.json
index 12f8de0fe8..edeb465c5b 100644
--- a/integration-tests/mdi/metadata/unit-test/0087-load-file-content-validate 
UNIT.json        
+++ b/integration-tests/mdi/metadata/unit-test/0054-load-file-content-validate 
UNIT.json        
@@ -152,7 +152,7 @@
     }
   ],
   "input_data_sets": [],
-  "name": "0087-load-file-content-validate UNIT",
+  "name": "0054-load-file-content-validate UNIT",
   "trans_test_tweaks": [],
-  "pipeline_filename": "./0087-load-file-content-validate.hpl"
+  "pipeline_filename": "./0054-load-file-content-validate.hpl"
 }
\ No newline at end of file
diff --git 
a/integration-tests/mdi/metadata/unit-test/0088-set-constant-value-parent 
UNIT.json 
b/integration-tests/mdi/metadata/unit-test/0055-set-constant-value-parent 
UNIT.json
similarity index 82%
rename from 
integration-tests/mdi/metadata/unit-test/0088-set-constant-value-parent 
UNIT.json
rename to 
integration-tests/mdi/metadata/unit-test/0055-set-constant-value-parent 
UNIT.json
index 1ce759f19c..f8d7ea2fe3 100644
--- a/integration-tests/mdi/metadata/unit-test/0088-set-constant-value-parent 
UNIT.json 
+++ b/integration-tests/mdi/metadata/unit-test/0055-set-constant-value-parent 
UNIT.json 
@@ -19,10 +19,10 @@
     }
   ],
   "input_data_sets": [],
-  "name": "0088-set-constant-value-parent UNIT",
+  "name": "0055-set-constant-value-parent UNIT",
   "description": "",
   "trans_test_tweaks": [],
   "persist_filename": "",
-  "pipeline_filename": "./0088-set-constant-value-parent.hpl",
+  "pipeline_filename": "./0055-set-constant-value-parent.hpl",
   "test_type": "UNIT_TEST"
 }
diff --git 
a/integration-tests/mdi/metadata/unit-test/0089-mdi-multi-datagrid-template 
UNIT.json 
b/integration-tests/mdi/metadata/unit-test/0056-mdi-multi-datagrid-template 
UNIT.json
similarity index 85%
rename from 
integration-tests/mdi/metadata/unit-test/0089-mdi-multi-datagrid-template 
UNIT.json
rename to 
integration-tests/mdi/metadata/unit-test/0056-mdi-multi-datagrid-template 
UNIT.json
index c97178eeca..197c4a187e 100644
--- a/integration-tests/mdi/metadata/unit-test/0089-mdi-multi-datagrid-template 
UNIT.json       
+++ b/integration-tests/mdi/metadata/unit-test/0056-mdi-multi-datagrid-template 
UNIT.json       
@@ -27,7 +27,7 @@
     }
   ],
   "input_data_sets": [],
-  "name": "0089-mdi-multi-datagrid-template UNIT",
+  "name": "0056-mdi-multi-datagrid-template UNIT",
   "trans_test_tweaks": [],
-  "pipeline_filename": "./0089-mdi-multi-datagrid-template-injected.hpl"
+  "pipeline_filename": "./0056-mdi-multi-datagrid-template-injected.hpl"
 }
diff --git 
a/integration-tests/mdi/metadata/unit-test/0090-mdi-shared-field-template 
UNIT.json 
b/integration-tests/mdi/metadata/unit-test/0057-mdi-shared-field-template 
UNIT.json
similarity index 85%
rename from 
integration-tests/mdi/metadata/unit-test/0090-mdi-shared-field-template 
UNIT.json
rename to 
integration-tests/mdi/metadata/unit-test/0057-mdi-shared-field-template 
UNIT.json
index d8807be526..45f1048eea 100644
--- a/integration-tests/mdi/metadata/unit-test/0090-mdi-shared-field-template 
UNIT.json 
+++ b/integration-tests/mdi/metadata/unit-test/0057-mdi-shared-field-template 
UNIT.json 
@@ -27,7 +27,7 @@
     }
   ],
   "input_data_sets": [],
-  "name": "0090-mdi-shared-field-template UNIT",
+  "name": "0057-mdi-shared-field-template UNIT",
   "trans_test_tweaks": [],
-  "pipeline_filename": "./0090-mdi-shared-field-template-injected.hpl"
+  "pipeline_filename": "./0057-mdi-shared-field-template-injected.hpl"
 }
diff --git 
a/integration-tests/mdi/metadata/unit-test/0091-mdi-edge-cases-template 
UNIT.json 
b/integration-tests/mdi/metadata/unit-test/0058-mdi-edge-cases-template 
UNIT.json
similarity index 88%
rename from 
integration-tests/mdi/metadata/unit-test/0091-mdi-edge-cases-template UNIT.json
rename to integration-tests/mdi/metadata/unit-test/0058-mdi-edge-cases-template 
UNIT.json
index b0e6adf20c..bb70d21dc3 100644
--- a/integration-tests/mdi/metadata/unit-test/0091-mdi-edge-cases-template 
UNIT.json   
+++ b/integration-tests/mdi/metadata/unit-test/0058-mdi-edge-cases-template 
UNIT.json   
@@ -37,7 +37,7 @@
     }
   ],
   "input_data_sets": [],
-  "name": "0091-mdi-edge-cases-template UNIT",
+  "name": "0058-mdi-edge-cases-template UNIT",
   "trans_test_tweaks": [],
-  "pipeline_filename": "./0091-mdi-edge-cases-template-injected.hpl"
+  "pipeline_filename": "./0058-mdi-edge-cases-template-injected.hpl"
 }
diff --git 
a/plugins/transforms/metainject/src/main/java/org/apache/hop/pipeline/transforms/metainject/MetaInject.java
 
b/plugins/transforms/metainject/src/main/java/org/apache/hop/pipeline/transforms/metainject/MetaInject.java
index db6d8e417a..58abda44b1 100644
--- 
a/plugins/transforms/metainject/src/main/java/org/apache/hop/pipeline/transforms/metainject/MetaInject.java
+++ 
b/plugins/transforms/metainject/src/main/java/org/apache/hop/pipeline/transforms/metainject/MetaInject.java
@@ -396,7 +396,7 @@ public class MetaInject extends 
BaseTransform<MetaInjectMeta, MetaInjectData> {
         // See if this is a constant without a source
         //
         if (StringUtils.isEmpty(mapping.getSourceTransformName())) {
-          addConstantToGroupData(mapping, injectionGroupData, groupKey);
+          addConstantToGroupData(this, mapping, injectionGroupData, groupKey);
         }
       }
     } else if (mapping.isTargetDetail()) {
@@ -405,7 +405,7 @@ public class MetaInject extends 
BaseTransform<MetaInjectMeta, MetaInjectData> {
       //
       if (HopMetadataInjector.isTopLevelInjectionKey(
           targetMetaClass, mapping.getTargetAttributeKey())) {
-        collectInjectionKeyValue(mapping, sourceRows, injectionKeyData);
+        collectInjectionKeyValue(this, mapping, sourceRows, injectionKeyData);
       } else {
         throw new HopTransformException(
             "The injection group key for target key '"
@@ -417,7 +417,7 @@ public class MetaInject extends 
BaseTransform<MetaInjectMeta, MetaInjectData> {
       // This also captures the "Constant" mappings where we don't have source 
rows to feed the
       // injection.
       //
-      collectInjectionKeyValue(mapping, sourceRows, injectionKeyData);
+      collectInjectionKeyValue(this, mapping, sourceRows, injectionKeyData);
     }
   }
 
@@ -488,8 +488,12 @@ public class MetaInject extends 
BaseTransform<MetaInjectMeta, MetaInjectData> {
    */
   record GroupColumn(String targetKey, String sourceTransformName, int 
columnIndex) {}
 
-  private static void addConstantToGroupData(
-      MetaInjectMapping mapping, Map<String, RowBuffer> injectionGroupData, 
String groupKey) {
+  // Package-private for unit testing of the constant-injection path (see 
MetaInjectTest).
+  static void addConstantToGroupData(
+      IVariables variables,
+      MetaInjectMapping mapping,
+      Map<String, RowBuffer> injectionGroupData,
+      String groupKey) {
     // We need to add or extend a single row in a row buffer for the given 
group.
     //
     RowBuffer rowBuffer = injectionGroupData.computeIfAbsent(groupKey, f -> 
new RowBuffer());
@@ -508,7 +512,8 @@ public class MetaInject extends 
BaseTransform<MetaInjectMeta, MetaInjectData> {
       row = rows.getFirst();
     }
     row = RowDataUtil.createResizedCopy(row, rowMeta.size());
-    row[rowMeta.size() - 1] = mapping.getSourceField();
+    // Resolve variables in the constant value, just like the legacy 
newInjectionConstants() path.
+    row[rowMeta.size() - 1] = variables.resolve(mapping.getSourceField());
     // Let's not forget to update the row after re-sizing it.
     rows.set(0, row);
   }
@@ -562,7 +567,9 @@ public class MetaInject extends 
BaseTransform<MetaInjectMeta, MetaInjectData> {
     return null;
   }
 
-  private static void collectInjectionKeyValue(
+  // Package-private for unit testing of the constant-injection path (see 
MetaInjectTest).
+  static void collectInjectionKeyValue(
+      IVariables variables,
       MetaInjectMapping mapping,
       List<RowMetaAndData> sourceRows,
       Map<String, Object> injectionKeyData)
@@ -571,8 +578,10 @@ public class MetaInject extends 
BaseTransform<MetaInjectMeta, MetaInjectData> {
       if (StringUtils.isEmpty(mapping.getSourceTransformName())) {
         // This is a constant String value to set.
         // The value is set in the source field.
+        // Resolve variables in the constant, just like the legacy 
newInjectionConstants() path.
         //
-        injectionKeyData.put(mapping.getTargetAttributeKey(), 
mapping.getSourceField());
+        injectionKeyData.put(
+            mapping.getTargetAttributeKey(), 
variables.resolve(mapping.getSourceField()));
       }
       return;
     }
diff --git 
a/plugins/transforms/metainject/src/test/java/org/apache/hop/pipeline/transforms/metainject/MetaInjectTest.java
 
b/plugins/transforms/metainject/src/test/java/org/apache/hop/pipeline/transforms/metainject/MetaInjectTest.java
index e364b40c9a..09d69dc333 100644
--- 
a/plugins/transforms/metainject/src/test/java/org/apache/hop/pipeline/transforms/metainject/MetaInjectTest.java
+++ 
b/plugins/transforms/metainject/src/test/java/org/apache/hop/pipeline/transforms/metainject/MetaInjectTest.java
@@ -42,6 +42,7 @@ import org.apache.hop.core.row.IRowMeta;
 import org.apache.hop.core.row.RowBuffer;
 import org.apache.hop.core.row.RowMeta;
 import org.apache.hop.core.row.value.ValueMetaString;
+import org.apache.hop.core.variables.Variables;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.pipeline.Pipeline;
 import org.apache.hop.pipeline.PipelineMeta;
@@ -189,6 +190,50 @@ class MetaInjectTest {
     assertNull(targetMeta.there);
   }
 
+  /**
+   * Regression test: a constant value containing variables must be resolved 
before it is injected
+   * into a {@code @HopMetadataProperty} template transform. The legacy {@code 
@InjectionSupported}
+   * path ({@link MetaInject#newInjectionConstants}) always resolved them; the 
rewritten
+   * scalar-constant path did not, so variables leaked through unresolved 
(worked in 2.17).
+   */
+  @Test
+  void collectInjectionKeyValue_resolvesVariablesInConstant() throws Exception 
{
+    Variables variables = new Variables();
+    variables.setVariable("MY_VAR", "resolved-value");
+
+    // A "constant" mapping: no source transform, the literal value sits in 
the source field.
+    MetaInjectMapping mapping = new MetaInjectMapping();
+    mapping.setTargetAttributeKey("SOME_KEY");
+    mapping.setSourceTransformName(null);
+    mapping.setSourceField("${MY_VAR}");
+
+    Map<String, Object> injectionKeyData = new HashMap<>();
+    MetaInject.collectInjectionKeyValue(variables, mapping, null, 
injectionKeyData);
+
+    assertEquals("resolved-value", injectionKeyData.get("SOME_KEY"));
+  }
+
+  /**
+   * Same regression as {@link 
#collectInjectionKeyValue_resolvesVariablesInConstant()} but for a
+   * constant that belongs to an injection group (list) key.
+   */
+  @Test
+  void addConstantToGroupData_resolvesVariablesInConstant() {
+    Variables variables = new Variables();
+    variables.setVariable("MY_VAR", "resolved-value");
+
+    MetaInjectMapping mapping = new MetaInjectMapping();
+    mapping.setTargetAttributeKey("SOME_KEY");
+    mapping.setSourceField("${MY_VAR}");
+
+    Map<String, RowBuffer> injectionGroupData = new HashMap<>();
+    MetaInject.addConstantToGroupData(variables, mapping, injectionGroupData, 
"GROUP");
+
+    RowBuffer buffer = injectionGroupData.get("GROUP");
+    assertNotNull(buffer);
+    assertEquals("resolved-value", buffer.getBuffer().getFirst()[0]);
+  }
+
   /**
    * Regression test for <a 
href="https://github.com/apache/hop/issues/7246";>#7246</a>: when an
    * injection group mixes a streamed key and a constant key, the constant 
value must be merged into

Reply via email to