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

gitgabrio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git


The following commit(s) were added to refs/heads/main by this push:
     new 356d4702586 [Incubator kie issues#2188] Fix the compilation failure on 
DecisionService–Decision output type mismatch (#6776)
356d4702586 is described below

commit 356d4702586b750089ffdf000fe804fd6816a7e7
Author: AthiraHari77 <[email protected]>
AuthorDate: Fri Jul 10 16:08:16 2026 +0530

    [Incubator kie issues#2188] Fix the compilation failure on 
DecisionService–Decision output type mismatch (#6776)
    
    * [incubator-kie-issues#2188] add coercion logic for decisionservice
    
    * [incubator-kie-issues#2188] WIP
    
    * [incubator-kie-issues#2188] update changes for date time conversion along 
with decision service handling
    
    * [incubator-kie-issues#2188] Fix test failures
    
    * [incubator-kie-issues#2188] Refactor code
    
    * Update tests and code refactoring
    
    * code refactoring
    
    * [incubator-kie-issues#2260] handle null result
    
    * [incubator-kie-issues#2260] wip
    
    * [incubator-kie-issues#2260] fix testcases
    
    * [incubator-kie-issues#2188] refactoring code
    
    * [incubator-kie-issues#2188] refactoring code
    
    ---------
    
    Co-authored-by: athira <[email protected]>
---
 .../dmn/core/ast/DMNDecisionServiceEvaluator.java  |  15 ++-
 ...DecisionServiceFunctionDefinitionEvaluator.java |   2 +-
 .../dmn/core/ast/DMNFunctionWithReturnType.java    |   2 +-
 .../dmn/core/compiler/DMNTypeRegistryAbstract.java |   5 +-
 .../dmn/core/compiler/DecisionServiceCompiler.java | 122 ++++++++++-----------
 .../java/org/kie/dmn/core/impl/DMNRuntimeImpl.java |   4 +-
 .../org/kie/dmn/core/impl/DMNRuntimeUtils.java     |  70 +++++++++++-
 .../core/compiler/DecisionServiceCompilerTest.java |   1 -
 .../decisionservices/DMNDecisionServicesTest.java  |  82 ++++++++++++++
 .../org/kie/dmn/core/impl/DMNRuntimeUtilsTest.java |  90 +++++++++++++++
 .../DecisionServiceImplicitConversions.dmn         |  85 ++++++++++++++
 11 files changed, 404 insertions(+), 74 deletions(-)

diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java
 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java
index fb5da420e79..b991e3941f0 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 import org.kie.dmn.api.core.DMNDecisionResult;
 import org.kie.dmn.api.core.DMNMessage;
@@ -30,6 +29,7 @@ import org.kie.dmn.api.core.DMNMessage.Severity;
 import org.kie.dmn.api.core.DMNModel;
 import org.kie.dmn.api.core.DMNResult;
 import org.kie.dmn.api.core.DMNRuntime;
+import org.kie.dmn.api.core.DMNType;
 import org.kie.dmn.api.core.ast.DecisionServiceNode;
 import org.kie.dmn.api.core.event.DMNRuntimeEventManager;
 import org.kie.dmn.core.api.DMNExpressionEvaluator;
@@ -41,6 +41,7 @@ import org.kie.dmn.core.impl.DMNResultImpl;
 import org.kie.dmn.core.impl.DMNRuntimeEventManagerUtils;
 import org.kie.dmn.core.impl.DMNRuntimeImpl;
 import org.kie.dmn.core.impl.DMNRuntimeUtils;
+import org.kie.dmn.core.util.CoerceUtil;
 import org.kie.dmn.core.util.Msg;
 import org.kie.dmn.core.util.MsgUtil;
 import org.slf4j.Logger;
@@ -73,7 +74,14 @@ public class DMNDecisionServiceEvaluator implements 
DMNExpressionEvaluator {
         for (String id : decisionIDs) {
             DMNDecisionResult decisionResultById = 
evaluateById.getDecisionResultById(id);
             String decisionName = dmnModel.getDecisionById(id).getName();
-            ctx.put(decisionName, decisionResultById.getResult());
+
+            DMNType expectedType = dsNode.getResultType();
+            Object originalResult = decisionResultById.getResult();
+            Object coercedResult = CoerceUtil.coerceValue(expectedType, 
originalResult);
+            if (coercedResult != originalResult) {
+                ((DMNDecisionResultImpl) 
decisionResultById).setResult(coercedResult);
+            }
+            ctx.put(decisionName, coercedResult);
             decisionResults.add(decisionResultById);
         }
         boolean errors = false;
@@ -85,7 +93,8 @@ public class DMNDecisionServiceEvaluator implements 
DMNExpressionEvaluator {
         }
         boolean typeCheck = ((DMNRuntimeImpl) 
eventManager.getRuntime()).performRuntimeTypeCheck(result.getModel());
         if (typeCheck) {
-            Object c = DMNRuntimeUtils.coerceUsingType(decisionIDs.size() == 1 
? ctx.values().iterator().next() : ctx,
+            Object finalResult = decisionIDs.size() == 1 ? 
ctx.values().iterator().next() : ctx;
+            Object c = 
DMNRuntimeUtils.coerceSingletonCollectionItemToValue(finalResult,
                                                        dsNode.getResultType(),
                                                        typeCheck,
                                                        (rx, tx) -> 
MsgUtil.reportMessage(LOG,
diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java
 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java
index d9053581c92..d0388e7d86c 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java
@@ -157,7 +157,7 @@ public class DMNDecisionServiceFunctionDefinitionEvaluator 
implements DMNExpress
 
         private Object performTypeCheckIfNeeded(Object param, int paramIndex) {
             DSFormalParameter dsFormalParameter = parameters.get(paramIndex);
-            Object result = DMNRuntimeUtils.coerceUsingType(param,
+            Object result = 
DMNRuntimeUtils.coerceSingletonCollectionItemToValue(param,
                                                             
dsFormalParameter.type,
                                                             typeCheck,
                                                             (rx, tx) -> 
MsgUtil.reportMessage(LOG,
diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionWithReturnType.java
 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionWithReturnType.java
index ebad93794e1..01236dddb53 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionWithReturnType.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionWithReturnType.java
@@ -59,7 +59,7 @@ public class DMNFunctionWithReturnType extends 
BaseFEELFunction {
     @Override
     public Object invokeReflectively(EvaluationContext ctx, Object[] params) {
         Object result = wrapped.invokeReflectively(ctx, params);
-        result = DMNRuntimeUtils.coerceUsingType(result,
+        result = DMNRuntimeUtils.coerceSingletonCollectionItemToValue(result,
                                                  returnType,
                                                  true, // this FN is created 
when typeCheck==true, hence here always true.
                                                  (r, t) -> 
MsgUtil.reportMessage(LOG,
diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DMNTypeRegistryAbstract.java
 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DMNTypeRegistryAbstract.java
index 9a4c233e7fd..d0697da3d11 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DMNTypeRegistryAbstract.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DMNTypeRegistryAbstract.java
@@ -72,7 +72,7 @@ public abstract class DMNTypeRegistryAbstract implements 
DMNTypeRegistry, FEELTy
         feelTypesScope.define(new TypeSymbol(name, type));
     }
 
-    static DMNType getFeelPrimitiveType(String name, BuiltInType type, String 
feelNamespace, DMNType unknownType) {
+     public static DMNType getFeelPrimitiveType(String name, BuiltInType type, 
String feelNamespace, DMNType unknownType) {
         DMNType feelPrimitiveType;
         if( type == BuiltInType.LIST ) {
             feelPrimitiveType = new SimpleTypeImpl(feelNamespace, name, null, 
true, null, null, unknownType, type);
@@ -152,5 +152,4 @@ public abstract class DMNTypeRegistryAbstract implements 
DMNTypeRegistry, FEELTy
         return null;
     }
 
-
-}
+}
\ No newline at end of file
diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DecisionServiceCompiler.java
 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DecisionServiceCompiler.java
index 42988f8facb..cc151160f6e 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DecisionServiceCompiler.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DecisionServiceCompiler.java
@@ -40,6 +40,7 @@ import org.kie.dmn.core.ast.DecisionServiceNodeImpl;
 import org.kie.dmn.core.ast.InputDataNodeImpl;
 import org.kie.dmn.core.ast.ItemDefNodeImpl;
 import org.kie.dmn.core.impl.DMNModelImpl;
+import org.kie.dmn.core.impl.DMNRuntimeUtils;
 import org.kie.dmn.core.impl.SimpleFnTypeImpl;
 import org.kie.dmn.core.util.Msg;
 import org.kie.dmn.core.util.MsgUtil;
@@ -149,7 +150,7 @@ public class DecisionServiceCompiler implements 
DRGElementCompiler {
         ni.setEvaluator(exprEvaluator);
 
         if (ni.getType() != null) {
-            checkFnConsistency(model, ni, ni.getType(), outputDecisions);
+            validateDecisionServiceFunctionSignature(model, ni, ni.getType(), 
outputDecisions);
         }
     }
 
@@ -216,115 +217,114 @@ public class DecisionServiceCompiler implements 
DRGElementCompiler {
                 ni.getName());
     }
 
-    private void checkFnConsistency(DMNModelImpl model, 
DecisionServiceNodeImpl ni, DMNType type, List<DecisionNode> outputDecisions) {
-        SimpleFnTypeImpl fnType = ((SimpleFnTypeImpl) type);
-        FunctionItem fi = fnType.getFunctionItem();
-        if (fi.getParameters().size() != ni.getInputParameters().size()) {
+    private void validateDecisionServiceFunctionSignature(DMNModelImpl model, 
DecisionServiceNodeImpl decisionServiceNode, DMNType 
decisionServiceFunctionType, List<DecisionNode> outputDecisions) {
+        SimpleFnTypeImpl functionType = ((SimpleFnTypeImpl) 
decisionServiceFunctionType);
+        FunctionItem functionItem = functionType.getFunctionItem();
+        if (functionItem.getParameters().size() != 
decisionServiceNode.getInputParameters().size()) {
             MsgUtil.reportMessage(LOG,
                                   DMNMessage.Severity.ERROR,
-                                  ni.getDecisionService(),
+                                  decisionServiceNode.getDecisionService(),
                                   model,
                                   null,
                                   null,
                                   Msg.PARAMETER_COUNT_MISMATCH_COMPILING,
-                                  ni.getName(),
-                                  fi.getParameters().size(),
-                                  ni.getInputParameters().size());
+                                  decisionServiceNode.getName(),
+                                  functionItem.getParameters().size(),
+                                  
decisionServiceNode.getInputParameters().size());
             return;
         }
-        for (int i = 0; i < fi.getParameters().size(); i++) {
-            InformationItem fiII = fi.getParameters().get(i);
-            String fpName = 
ni.getInputParameters().keySet().stream().skip(i).findFirst().orElse(null);
-            if (!fiII.getName().equals(fpName)) {
-                List<String> fiParamNames = 
fi.getParameters().stream().map(InformationItem::getName).collect(Collectors.toList());
-                List<String> funcDefParamNames = 
ni.getInputParameters().keySet().stream().collect(Collectors.toList());
+        for (int i = 0; i < functionItem.getParameters().size(); i++) {
+            InformationItem functionParameter = 
functionItem.getParameters().get(i);
+            String functionParameterName = 
decisionServiceNode.getInputParameters().keySet().stream().skip(i).findFirst().orElse(null);
+            if (!functionParameter.getName().equals(functionParameterName)) {
+                List<String> functionItemParamNames = 
functionItem.getParameters().stream().map(InformationItem::getName).collect(Collectors.toList());
+                List<String> decisionServiceParamNames = 
decisionServiceNode.getInputParameters().keySet().stream().collect(Collectors.toList());
                 MsgUtil.reportMessage(LOG,
                                       DMNMessage.Severity.ERROR,
-                                      ni.getDecisionService(),
+                                      decisionServiceNode.getDecisionService(),
                                       model,
                                       null,
                                       null,
                                       Msg.PARAMETER_NAMES_MISMATCH_COMPILING,
-                                      ni.getName(),
-                                      fiParamNames,
-                                      funcDefParamNames);
+                                      decisionServiceNode.getName(),
+                                      functionItemParamNames,
+                                      decisionServiceParamNames);
                 return;
             }
-            QName fiQname = fiII.getTypeRef();
-            QName fdQname = null;
-            DMNNode fpDMNNode = ni.getInputParameters().get(fpName);
-            if (fpDMNNode instanceof InputDataNodeImpl) {
-                fdQname = ((InputDataNodeImpl) 
fpDMNNode).getInputData().getVariable().getTypeRef();
-            } else if (fpDMNNode instanceof DecisionNodeImpl) {
-                fdQname = ((DecisionNodeImpl) 
fpDMNNode).getDecision().getVariable().getTypeRef();
+            QName functionParameterTypeRef = functionParameter.getTypeRef();
+            QName decisionServiceParameterTypeRef = null;
+            DMNNode inputParameterNode = 
decisionServiceNode.getInputParameters().get(functionParameterName);
+            if (inputParameterNode instanceof InputDataNodeImpl) {
+                decisionServiceParameterTypeRef = ((InputDataNodeImpl) 
inputParameterNode).getInputData().getVariable().getTypeRef();
+            } else if (inputParameterNode instanceof DecisionNodeImpl) {
+                decisionServiceParameterTypeRef = ((DecisionNodeImpl) 
inputParameterNode).getDecision().getVariable().getTypeRef();
             }
-            if (fiQname != null && fdQname != null && 
!fiQname.equals(fdQname)) {
+            if (functionParameterTypeRef != null && 
decisionServiceParameterTypeRef != null && 
!functionParameterTypeRef.equals(decisionServiceParameterTypeRef)) {
                 MsgUtil.reportMessage(LOG,
                                       DMNMessage.Severity.ERROR,
-                                      ni.getDecisionService(),
+                                      decisionServiceNode.getDecisionService(),
                                       model,
                                       null,
                                       null,
                                       Msg.PARAMETER_TYPEREF_MISMATCH_COMPILING,
-                                      ni.getName(),
-                                      fiII.getName(),
-                                      fiQname,
-                                      fdQname);
+                                      decisionServiceNode.getName(),
+                                      functionParameter.getName(),
+                                      functionParameterTypeRef,
+                                      decisionServiceParameterTypeRef);
             }
         }
-        QName fiReturnType = fi.getOutputTypeRef();
-        if (ni.getDecisionService().getOutputDecision().size() == 1) {
-            QName fdReturnType = 
outputDecisions.get(0).getDecision().getVariable().getTypeRef();
-            if (fiReturnType != null && fdReturnType != null && 
!fiReturnType.equals(fdReturnType)) {
+        QName functionReturnTypeRef = functionItem.getOutputTypeRef();
+        if 
(decisionServiceNode.getDecisionService().getOutputDecision().size() == 1) {
+            QName outputDecisionReturnTypeRef = 
outputDecisions.get(0).getDecision().getVariable().getTypeRef();
+            if (functionReturnTypeRef != null && outputDecisionReturnTypeRef 
!= null && !functionReturnTypeRef.equals(outputDecisionReturnTypeRef) && 
!DMNRuntimeUtils.isReturnTypeCollectionCompatible(functionReturnTypeRef, 
outputDecisionReturnTypeRef, model)) {
                 MsgUtil.reportMessage(LOG,
                                       DMNMessage.Severity.ERROR,
-                                      ni.getDecisionService(),
+                                      decisionServiceNode.getDecisionService(),
                                       model,
                                       null,
                                       null,
                                       
Msg.RETURNTYPE_TYPEREF_MISMATCH_COMPILING,
-                                      ni.getName(),
-                                      fiReturnType,
-                                      fdReturnType);
+                                      decisionServiceNode.getName(),
+                                      functionReturnTypeRef,
+                                      outputDecisionReturnTypeRef);
             }
-        } else if (ni.getDecisionService().getOutputDecision().size() > 1) {
-            final Function<QName, QName> lookupFn = (in) -> 
NamespaceUtil.getNamespaceAndName(ni.getDecisionService(), 
model.getImportAliasesForNS(), in, model.getNamespace());
-            LinkedHashMap<String, QName> fdComposite = new LinkedHashMap<>();
-            for (DecisionNode dn : outputDecisions) {
-                fdComposite.put(dn.getName(), 
lookupFn.apply(dn.getDecision().getVariable().getTypeRef()));
+        } else if 
(decisionServiceNode.getDecisionService().getOutputDecision().size() > 1) {
+            final Function<QName, QName> namespaceQNameLookup = (qname) -> 
NamespaceUtil.getNamespaceAndName(decisionServiceNode.getDecisionService(), 
model.getImportAliasesForNS(), qname, model.getNamespace());
+            LinkedHashMap<String, QName> decisionServiceCompositeType = new 
LinkedHashMap<>();
+            for (DecisionNode decisionNode : outputDecisions) {
+                decisionServiceCompositeType.put(decisionNode.getName(), 
namespaceQNameLookup.apply(decisionNode.getDecision().getVariable().getTypeRef()));
             }
-            final QName lookup = lookupFn.apply(fiReturnType);
-            Optional<ItemDefNodeImpl> composite = 
model.getItemDefinitions().stream().filter(id -> 
id.getModelNamespace().equals(lookup.getNamespaceURI()) && 
id.getName().equals(lookup.getLocalPart())).map(ItemDefNodeImpl.class::cast).findFirst();
-            if (composite.isEmpty()) {
+            final QName resolvedFunctionReturnTypeRef = 
namespaceQNameLookup.apply(functionReturnTypeRef);
+            Optional<ItemDefNodeImpl> matchedItemDefNode = 
model.getItemDefinitions().stream().filter(id -> 
id.getModelNamespace().equals(resolvedFunctionReturnTypeRef.getNamespaceURI()) 
&& 
id.getName().equals(resolvedFunctionReturnTypeRef.getLocalPart())).map(ItemDefNodeImpl.class::cast).findFirst();
+            if (matchedItemDefNode.isEmpty()) {
                 MsgUtil.reportMessage(LOG,
                                       DMNMessage.Severity.ERROR,
-                                      ni.getDecisionService(),
+                                      decisionServiceNode.getDecisionService(),
                                       model,
                                       null,
                                       null,
                                       
Msg.RETURNTYPE_TYPEREF_MISMATCH_COMPILING,
-                                      ni.getName(),
-                                      lookup,
-                                      fdComposite);
+                                      decisionServiceNode.getName(),
+                                      resolvedFunctionReturnTypeRef,
+                                      decisionServiceCompositeType);
                 return;
             }
-            LinkedHashMap<String, QName> fiComposite = new LinkedHashMap<>();
-            for (ItemDefinition ic : 
composite.get().getItemDef().getItemComponent()) {
-                fiComposite.put(ic.getName(), lookupFn.apply(ic.getTypeRef()));
+            LinkedHashMap<String, QName> functionCompositeType = new 
LinkedHashMap<>();
+            for (ItemDefinition itemDefinition : 
matchedItemDefNode.get().getItemDef().getItemComponent()) {
+                functionCompositeType.put(itemDefinition.getName(), 
namespaceQNameLookup.apply(itemDefinition.getTypeRef()));
             }
-            if (!fiComposite.equals(fdComposite)) {
+            if (!functionCompositeType.equals(decisionServiceCompositeType)) {
                 MsgUtil.reportMessage(LOG,
                                       DMNMessage.Severity.ERROR,
-                                      ni.getDecisionService(),
+                                      decisionServiceNode.getDecisionService(),
                                       model,
                                       null,
                                       null,
                                       
Msg.RETURNTYPE_TYPEREF_MISMATCH_COMPILING,
-                                      ni.getName(),
-                                      fiComposite,
-                                      fdComposite);
+                                      decisionServiceNode.getName(),
+                                      functionCompositeType,
+                                      decisionServiceCompositeType);
             }
         }
     }
-
 }
\ No newline at end of file
diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java
index 3789c799bee..41eb748ff14 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java
@@ -66,7 +66,7 @@ import static 
org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.EV
 import static 
org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.FAILED;
 import static 
org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.SKIPPED;
 import static org.kie.dmn.core.compiler.UnnamedImportUtils.isInUnnamedImport;
-import static org.kie.dmn.core.impl.DMNRuntimeUtils.coerceUsingType;
+import static 
org.kie.dmn.core.impl.DMNRuntimeUtils.coerceSingletonCollectionItemToValue;
 import static org.kie.dmn.core.impl.DMNRuntimeUtils.getDependencyIdentifier;
 import static org.kie.dmn.core.impl.DMNRuntimeUtils.getIdentifier;
 import static org.kie.dmn.core.impl.DMNRuntimeUtils.getObjectString;
@@ -316,7 +316,7 @@ public class DMNRuntimeImpl
                     } else if (dep instanceof DecisionNode) {
                         depType = ((DecisionNode) dep).getResultType();
                     }
-                    Object c = coerceUsingType(originalValue,
+                    Object c = 
coerceSingletonCollectionItemToValue(originalValue,
                                                depType,
                                                typeCheck,
                                                (r, t) -> 
MsgUtil.reportMessage(logger,
diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeUtils.java 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeUtils.java
index 1158e1539ad..692abe0d122 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeUtils.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeUtils.java
@@ -18,6 +18,7 @@
  */
 package org.kie.dmn.core.impl;
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
@@ -26,11 +27,15 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.BiConsumer;
+import javax.xml.namespace.QName;
 import org.kie.dmn.api.core.DMNContext;
 import org.kie.dmn.api.core.DMNType;
 import org.kie.dmn.api.core.ast.DMNNode;
 import org.kie.dmn.api.core.ast.InputDataNode;
+import org.kie.dmn.core.compiler.DMNTypeRegistryAbstract;
 import org.kie.dmn.core.util.MsgUtil;
+import org.kie.dmn.feel.lang.types.BuiltInType;
+import org.kie.dmn.typesafe.DMNTypeUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,7 +51,13 @@ public class DMNRuntimeUtils {
     }
 
 
-    public static Object coerceUsingType(Object value, DMNType type, boolean 
typeCheck,
+    /**
+     * When type-checking is enabled, verifies that {@code value} is 
assignable to {@code type} and, if the type is
+     * a non-collection type and {@code value} is a single-item Collection, 
unwraps the sole element.
+     * When type-checking is disabled, unconditionally attempts the 
single-item unwrap.
+     *
+     */
+    public static Object coerceSingletonCollectionItemToValue(Object value, 
DMNType type, boolean typeCheck,
                                          BiConsumer<Object, DMNType> 
nullCallback) {
         if (typeCheck) {
             if (type.isAssignableValue(value)) {
@@ -273,4 +284,59 @@ public class DMNRuntimeUtils {
     static String getIdentifier(DMNNode node) {
         return node.getName() != null ? node.getName() : node.getId();
     }
-}
+
+    /**
+     * Determines whether a function return-type reference and an 
output-decision return-type reference are
+     * compatible under DMN collection-coercion rules (e.g. a scalar type is 
compatible with a single-element
+     * collection of the same base type, and {@code date and time} is 
compatible with {@code date}).
+     *
+     * @param functionReturnTypeRef        the {@link QName} declared as the 
function's output type
+     * @param outputDecisionReturnTypeRef  the {@link QName} declared as the 
output decision's variable type
+     * @param model                        the DMN model used to resolve both 
type references
+     * @return {@code true} when the two types are collection-coercion 
compatible
+     */
+    public static boolean isReturnTypeCollectionCompatible(QName 
functionReturnTypeRef, QName outputDecisionReturnTypeRef, DMNModelImpl model) {
+        DMNType decisionServiceOutputType = 
resolveDMNType(functionReturnTypeRef, model);
+        DMNType decisionOutputType = 
resolveDMNType(outputDecisionReturnTypeRef, model);
+
+        if (decisionServiceOutputType == null || decisionOutputType == null) {
+            return false;
+        }
+        if (!decisionServiceOutputType.isCollection() && 
decisionOutputType.isCollection()) {
+            DMNType outputDecisionElementType = 
decisionOutputType.getBaseType();
+            return outputDecisionElementType == null || 
DMNTypeUtils.getFEELBuiltInType(outputDecisionElementType)
+                    == 
DMNTypeUtils.getFEELBuiltInType(decisionServiceOutputType);
+        }
+        if (decisionServiceOutputType.isCollection() && 
!decisionOutputType.isCollection()) {
+            DMNType decisionServiceElementType = 
decisionServiceOutputType.getBaseType();
+            return decisionServiceElementType != null && 
DMNTypeUtils.getFEELBuiltInType(decisionServiceElementType)
+                    == DMNTypeUtils.getFEELBuiltInType(decisionOutputType);
+        }
+        return decisionServiceOutputType instanceof SimpleTypeImpl 
decisionServiceSimpleType
+                && decisionServiceSimpleType.getFeelType() == 
BuiltInType.DATE_TIME
+                && decisionOutputType instanceof SimpleTypeImpl 
decisionOutputSimpleType
+                && decisionOutputSimpleType.getFeelType() == BuiltInType.DATE;
+    }
+
+    /**
+     * Resolves a {@link DMNType} from a {@link QName} by first consulting the 
model's type registry, then falling
+     * back to {@link DMNTypeRegistryAbstract#getFeelPrimitiveType} for 
built-in FEEL types.
+     *
+     * @param typeRef the qualified type reference to resolve
+     * @param model the DMN model whose registry is searched first
+     * @return the resolved {@link DMNType}, or {@code null} if neither the 
registry nor the built-in types match
+     */
+    public static DMNType resolveDMNType(QName typeRef, DMNModelImpl model) {
+        DMNType type = 
model.getTypeRegistry().resolveType(model.getNamespace(), 
typeRef.getLocalPart());
+        if (type != null) {
+            return type;
+        }
+        // determineTypeFromName returns UNKNOWN both for a genuine no-match 
and for the literal "unknown"/"any"
+        return Arrays.stream(BuiltInType.values())
+                .filter(b -> 
Arrays.asList(b.getNames()).contains(typeRef.getLocalPart()))
+                .findFirst()
+                .map(b -> 
DMNTypeRegistryAbstract.getFeelPrimitiveType(b.getName(), b, 
model.getNamespace(), model.getTypeRegistry().unknown()))
+                .orElse(null);
+    }
+
+}
\ No newline at end of file
diff --git 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/compiler/DecisionServiceCompilerTest.java
 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/compiler/DecisionServiceCompilerTest.java
index 8004538c47f..0e1c10fb771 100644
--- 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/compiler/DecisionServiceCompilerTest.java
+++ 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/compiler/DecisionServiceCompilerTest.java
@@ -31,7 +31,6 @@ import org.kie.dmn.model.api.Definitions;
 import org.kie.dmn.model.api.Import;
 import org.kie.dmn.model.api.NamedElement;
 import org.mockito.MockedStatic;
-import org.mockito.Mockito;
 
 import javax.xml.namespace.QName;
 import java.util.List;
diff --git 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/decisionservices/DMNDecisionServicesTest.java
 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/decisionservices/DMNDecisionServicesTest.java
index 10fb8af9a3b..49e4960a7ea 100644
--- 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/decisionservices/DMNDecisionServicesTest.java
+++ 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/decisionservices/DMNDecisionServicesTest.java
@@ -19,6 +19,8 @@
 package org.kie.dmn.core.decisionservices;
 
 import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.util.List;
 import java.util.Map;
 
 import org.junit.jupiter.params.ParameterizedTest;
@@ -32,6 +34,7 @@ import org.kie.dmn.core.BaseInterpretedVsCompiledTest;
 import org.kie.dmn.core.api.DMNFactory;
 import org.kie.dmn.core.compiler.CoerceDecisionServiceSingletonOutputOption;
 import org.kie.dmn.core.util.DMNRuntimeUtil;
+import org.kie.dmn.feel.runtime.custom.FormattedZonedDateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -733,4 +736,83 @@ public class DMNDecisionServicesTest extends 
BaseInterpretedVsCompiledTest {
 
         assertSupplyingPersonname(runtime, dmnModel);
     }
+
+    // 
=========================================================================
+    // Integration tests — DecisionServiceImplicitConversions.dmn 
(incubator-kie-issues#2188)
+    //
+    // DS1 "To Singleton List DS":          body typeRef=date,     DS 
typeRef=dateList
+    //     → evaluator wraps scalar date into a singleton dateList
+    // DS2 "From Singleton List DS":        body typeRef=dateList,  DS 
typeRef=date
+    //     → evaluator unwraps singleton dateList to a scalar date
+    // DS3 "From Date to Date and Time DS": body typeRef=date,      DS 
typeRef=date and time
+    //     → evaluator coerces LocalDate to ZonedDateTime at midnight UTC
+    // 
=========================================================================
+
+    private static final String NS = 
"https://kie.org/dmn/_F9BB5760-8BCA-4216-AAD9-8BD4FB70802D";;
+    private static final String NAME = "1157-implicit-conversions-DS";
+    private static final String FILE_NAME = 
"valid_models/DMNv1_6/DecisionService/DecisionServiceImplicitConversions.dmn";
+
+    @ParameterizedTest
+    @MethodSource("params")
+    void implicitConversionToSingletonList(boolean useExecModelCompiler) {
+        init(useExecModelCompiler);
+        final DMNRuntime runtime = DMNRuntimeUtil.createRuntime(FILE_NAME, 
this.getClass());
+        final DMNModel dmnModel = runtime.getModel(NS, NAME);
+        assertThat(dmnModel).isNotNull();
+        
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+
+        final DMNResult dmnResult = runtime.evaluateDecisionService(dmnModel, 
DMNFactory.newContext(), "To Singleton List DS");
+        LOG.debug("{}", dmnResult);
+        dmnResult.getDecisionResults().forEach(x -> LOG.debug("{}", x));
+        
assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse();
+
+        // Body 1 returns date(2000,1,2) — a scalar date; the DS wraps it into 
a singleton dateList
+        Object result = dmnResult.getContext().get("Body 1");
+        assertThat(result).isInstanceOf(List.class);
+        assertThat((List<Object>) result).containsExactly(LocalDate.of(2000, 
1, 2));
+    }
+
+    @ParameterizedTest
+    @MethodSource("params")
+    void implicitConversionFromSingletonListDS(boolean useExecModelCompiler) {
+        init(useExecModelCompiler);
+        final DMNRuntime runtime = DMNRuntimeUtil.createRuntime(FILE_NAME, 
this.getClass());
+        final DMNModel dmnModel = runtime.getModel(NS, NAME);
+        assertThat(dmnModel).isNotNull();
+        
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+
+        final DMNResult dmnResult = runtime.evaluateDecisionService(dmnModel, 
DMNFactory.newContext(), "From Singleton List DS");
+        LOG.debug("{}", dmnResult);
+        dmnResult.getDecisionResults().forEach(x -> LOG.debug("{}", x));
+        
assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse();
+
+        // Body 2 returns [date(2000,1,2)] — a singleton list; the DS unwraps 
it to the scalar date
+        assertThat(dmnResult.getContext().get("Body 
2")).isEqualTo(LocalDate.of(2000, 1, 2));
+    }
+
+    @ParameterizedTest
+    @MethodSource("params")
+    void implicitConversionfromDateToDateTimeDS(boolean useExecModelCompiler) {
+        init(useExecModelCompiler);
+        final DMNRuntime runtime = DMNRuntimeUtil.createRuntime(FILE_NAME, 
this.getClass());
+        final DMNModel dmnModel = runtime.getModel(NS, NAME);
+        assertThat(dmnModel).isNotNull();
+        
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+
+        final DMNResult dmnResult = runtime.evaluateDecisionService(dmnModel, 
DMNFactory.newContext(), "From Date to Date and Time DS");
+        LOG.debug("{}", dmnResult);
+        dmnResult.getDecisionResults().forEach(x -> LOG.debug("{}", x));
+        
assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse();
+
+        // Body 3 returns date(2000,1,2) — the DS coerces it to a 
ZonedDateTime at midnight UTC
+        Object result = dmnResult.getContext().get("Body 3");
+        assertThat(result).isInstanceOf(FormattedZonedDateTime.class);
+        FormattedZonedDateTime zdt = (FormattedZonedDateTime) result;
+        assertThat(zdt.getZonedDateTime().getYear()).isEqualTo(2000);
+        assertThat(zdt.getZonedDateTime().getMonthValue()).isEqualTo(1);
+        assertThat(zdt.getZonedDateTime().getDayOfMonth()).isEqualTo(2);
+        assertThat(zdt.getZonedDateTime().getHour()).isEqualTo(0);
+        assertThat(zdt.getZonedDateTime().getMinute()).isEqualTo(0);
+        assertThat(zdt.getZonedDateTime().getSecond()).isEqualTo(0);
+    }
 }
diff --git 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeUtilsTest.java
 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeUtilsTest.java
index fb19c68a80e..295a86d28bb 100644
--- 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeUtilsTest.java
+++ 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeUtilsTest.java
@@ -27,12 +27,15 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.IntStream;
+import javax.xml.namespace.QName;
 import org.junit.jupiter.api.Test;
 import org.kie.dmn.api.core.DMNContext;
 import org.kie.dmn.api.core.DMNType;
 import org.kie.dmn.api.core.ast.DMNNode;
 import org.kie.dmn.api.core.ast.InputDataNode;
 import org.kie.dmn.core.ast.InputDataNodeImpl;
+import org.kie.dmn.core.compiler.DMNTypeRegistryV16;
+import org.kie.dmn.feel.lang.types.BuiltInType;
 import org.kie.dmn.model.api.Definitions;
 import org.kie.dmn.model.api.InputData;
 
@@ -445,6 +448,93 @@ class DMNRuntimeUtilsTest {
         assertThat(DMNRuntimeUtils.getIdentifier(dmnNode)).isEqualTo(name);
     }
 
+    // decisionServiceOutputType=scalar "string", 
decisionOutputType=collection "tDateList" (base=date) — bases differ → false
+    @Test
+    void isReturnTypeCollectionCompatible_incompatible() {
+        final String ns = "ns";
+        DMNTypeRegistryV16 registry = new DMNTypeRegistryV16(null);
+        SimpleTypeImpl dateType = new SimpleTypeImpl(ns, "date", null, false, 
null, null, null, BuiltInType.DATE);
+        SimpleTypeImpl tDateList = new SimpleTypeImpl(ns, "tDateList", null, 
true, null, null, dateType, BuiltInType.DATE);
+        registry.registerType(tDateList);
+
+        DMNModelImpl model = mock(DMNModelImpl.class);
+        when(model.getNamespace()).thenReturn(ns);
+        when(model.getTypeRegistry()).thenReturn(registry);
+
+        assertThat(DMNRuntimeUtils.isReturnTypeCollectionCompatible(
+                new QName(ns, "string"), new QName(ns, "tDateList"), 
model)).isFalse();
+    }
+
+    // decisionServiceOutputType=scalar "date", decisionOutputType=collection 
"tDateList" (base=date) — same base → true
+    @Test
+    void isReturnTypeCollectionCompatible_scalarFiCollectionFd() {
+        final String ns = "ns";
+        DMNTypeRegistryV16 registry = new DMNTypeRegistryV16(null);
+        SimpleTypeImpl dateType = new SimpleTypeImpl(ns, "date", null, false, 
null, null, null, BuiltInType.DATE);
+        SimpleTypeImpl tDateList = new SimpleTypeImpl(ns, "tDateList", null, 
true, null, null, dateType, BuiltInType.DATE);
+        registry.registerType(tDateList);
+
+        DMNModelImpl model = mock(DMNModelImpl.class);
+        when(model.getNamespace()).thenReturn(ns);
+        when(model.getTypeRegistry()).thenReturn(registry);
+
+        assertThat(DMNRuntimeUtils.isReturnTypeCollectionCompatible(
+                new QName(ns, "date"), new QName(ns, "tDateList"), 
model)).isTrue();
+    }
+
+    // decisionServiceOutputType=collection "tDateList" (base=date), 
decisionOutputType=scalar "date" — compatible → true
+    @Test
+    void isReturnTypeCollectionCompatible_collectionFiScalarFd() {
+        final String ns = "ns";
+        DMNTypeRegistryV16 registry = new DMNTypeRegistryV16(null);
+        SimpleTypeImpl dateType = new SimpleTypeImpl(ns, "date", null, false, 
null, null, null, BuiltInType.DATE);
+        SimpleTypeImpl tDateList = new SimpleTypeImpl(ns, "tDateList", null, 
true, null, null, dateType, BuiltInType.DATE);
+        registry.registerType(tDateList);
+
+        DMNModelImpl model = mock(DMNModelImpl.class);
+        when(model.getNamespace()).thenReturn(ns);
+        when(model.getTypeRegistry()).thenReturn(registry);
+
+        assertThat(DMNRuntimeUtils.isReturnTypeCollectionCompatible(
+                new QName(ns, "tDateList"), new QName(ns, "date"), 
model)).isTrue();
+    }
+
+    // decisionServiceOutputType="date and time", decisionOutputType="date" — 
date-to-dateTime coercion pattern → true
+    @Test
+    void isReturnTypeCollectionCompatible_dateTimeAndDateCompatible() {
+        DMNTypeRegistryV16 registry = new DMNTypeRegistryV16(null);
+        DMNModelImpl model = mock(DMNModelImpl.class);
+        when(model.getNamespace()).thenReturn("ns");
+        when(model.getTypeRegistry()).thenReturn(registry);
+
+        assertThat(DMNRuntimeUtils.isReturnTypeCollectionCompatible(
+                new QName("", "date and time"), new QName("", "date"), 
model)).isTrue();
+    }
+
+    // decisionServiceOutputType="date", decisionOutputType="date and time" — 
order matters → false
+    @Test
+    void isReturnTypeCollectionCompatible_dateAndDateTimeIncompatible() {
+        DMNTypeRegistryV16 registry = new DMNTypeRegistryV16(null);
+        DMNModelImpl model = mock(DMNModelImpl.class);
+        when(model.getNamespace()).thenReturn("ns");
+        when(model.getTypeRegistry()).thenReturn(registry);
+
+        assertThat(DMNRuntimeUtils.isReturnTypeCollectionCompatible(
+                new QName("", "date"), new QName("", "date and time"), 
model)).isFalse();
+    }
+
+    // either typeRef is unknown — resolveDMNType returns null → false
+    @Test
+    void isReturnTypeCollectionCompatible_unknownTypeRef() {
+        DMNTypeRegistryV16 registry = new DMNTypeRegistryV16(null);
+        DMNModelImpl model = mock(DMNModelImpl.class);
+        when(model.getNamespace()).thenReturn("ns");
+        when(model.getTypeRegistry()).thenReturn(registry);
+
+        assertThat(DMNRuntimeUtils.isReturnTypeCollectionCompatible(
+                new QName("", "not-a-type"), new QName("", "date"), 
model)).isFalse();
+    }
+
     private static class OverflowingObject {
 
         String string;
diff --git 
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/DecisionService/DecisionServiceImplicitConversions.dmn
 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/DecisionService/DecisionServiceImplicitConversions.dmn
new file mode 100644
index 00000000000..ba121ff86c8
--- /dev/null
+++ 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/DecisionService/DecisionServiceImplicitConversions.dmn
@@ -0,0 +1,85 @@
+<?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.
+-->
+<definitions xmlns="https://www.omg.org/spec/DMN/20230324/MODEL/";
+             xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/";
+             xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/";
+             xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/";
+             xmlns:kie="https://kie.org/dmn/extensions/1.0";
+             expressionLanguage="https://www.omg.org/spec/DMN/20230324/FEEL/";
+             
namespace="https://kie.org/dmn/_F9BB5760-8BCA-4216-AAD9-8BD4FB70802D";
+             id="_B6EF67C0-8376-4854-8D71-79484E1DBF39"
+             name="1157-implicit-conversions-DS">
+
+    <!-- ── Custom collection types ──────────────────────────────────────── 
-->
+    <itemDefinition id="_7546A1B0-00DF-40AB-B2CD-6ED845798BAA" name="dateList" 
isCollection="true">
+        <typeRef>date</typeRef>
+    </itemDefinition>
+
+    <!-- ── FunctionItem-based DS types ──────────────────────────────────── 
-->
+    <!-- DS1: function returning dateList (scalar date output → wrapped to 
list) -->
+    <itemDefinition id="_7546A1B0-00DF-40AB-B2CD-6ED845798BAE" 
name="functionReturningDateList">
+        <functionItem outputTypeRef="dateList" 
id="_DC20B4DF-E952-43B8-8CAB-AE78FD7E5F10" />
+    </itemDefinition>
+    <!-- DS2: function returning date (dateList output → unwrapped to scalar) 
-->
+    <itemDefinition id="_7546A1B0-00DF-40AB-B2CD-6ED845798BAF" 
name="functionReturningDate">
+        <functionItem outputTypeRef="date" 
id="_E1AEDADB-A715-4AF9-B312-A60619877709" />
+    </itemDefinition>
+    <!-- DS3: function returning date and time (date output → coerced to 
dateTime) -->
+    <itemDefinition id="_7546A1B0-00DF-40AB-B2CD-6ED845798BAD" 
name="functionReturningDateTime">
+        <functionItem outputTypeRef="date and time" 
id="_8FBD47B9-9EA7-4A08-9AAA-7858B9D62B55" />
+    </itemDefinition>
+
+    <!-- ── DS1: scalar date → singleton dateList ────────────────────────── 
-->
+    <decisionService name="To Singleton List DS" 
id="_BF3F2933-A588-41F1-AC98-492A79088A53">
+        <variable name="To Singleton List DS" 
id="_4C2AB9A4-BDB1-4BC4-A9B6-040020AA235E" typeRef="functionReturningDateList" 
/>
+        <outputDecision href="#_B3384D41-36C1-414E-A48D-FF817F728BB2" />
+    </decisionService>
+    <decision name="Body 1" id="_B3384D41-36C1-414E-A48D-FF817F728BB2">
+        <variable id="_9F749E69-EDEB-4B02-9130-E32E0F1065A1" typeRef="date" 
name="Body 1" />
+        <literalExpression id="_56188658-200B-4385-99B0-72CC17A8A6F7" 
typeRef="date">
+            <text>date(2000, 1, 2)</text>
+        </literalExpression>
+    </decision>
+
+    <!-- ── DS2: singleton dateList → scalar date ────────────────────────── 
-->
+    <decisionService name="From Singleton List DS" 
id="_79630040-ED4D-4656-A7E8-700D5DF62B3F">
+        <variable name="From Singleton List DS" 
id="_6888721D-A77C-4EEB-BB53-0248D23E1B68" typeRef="functionReturningDate" />
+        <outputDecision href="#_A8E5ACA2-02C8-4424-A826-AC330FF424FF" />
+    </decisionService>
+    <decision name="Body 2" id="_A8E5ACA2-02C8-4424-A826-AC330FF424FF">
+        <variable id="_0B08A715-E336-4F39-8665-159D51BD30A7" 
typeRef="dateList" name="Body 2" />
+        <literalExpression id="_0A455E79-9FD3-469E-8917-099508B742DB" 
typeRef="dateList">
+            <text>[date(2000, 1, 2)]</text>
+        </literalExpression>
+    </decision>
+
+    <!-- ── DS3: date → date and time ────────────────────────────────────── 
-->
+    <decisionService name="From Date to Date and Time DS" 
id="_44150402-E698-4F84-B30D-51BB159F9E92">
+        <variable name="From Date to Date and Time DS" 
id="_A2C1C994-4A9C-4CF0-9062-4A9469E2779A" typeRef="functionReturningDateTime" 
/>
+        <outputDecision href="#_9B10A67E-B994-492A-BB53-089F22A8B9D4" />
+    </decisionService>
+    <decision name="Body 3" id="_9B10A67E-B994-492A-BB53-089F22A8B9D4">
+        <variable id="_EDE24ED4-A39B-4FFF-9C67-11369F5F67D6" typeRef="date" 
name="Body 3" />
+        <literalExpression id="_363B48FD-4E56-4176-BA21-0B619143EEE7" 
typeRef="date">
+            <text>date(2000, 1, 2)</text>
+        </literalExpression>
+    </decision>
+
+</definitions>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to