From ff9b28250dc0c016b37477536ece0b14b6d07c03 Mon Sep 17 00:00:00 2001
From: Mahendra Singh Thalor <mahi6run@gmail.com>
Date: Wed, 9 Jul 2025 11:42:47 +0530
Subject: [PATCH] implement setNodeValue function

DB-2978
---
 contrib/dbms_xmldom/dbms_xmldom.c             | 58 ++++++++++++++++++-
 contrib/dbms_xmldom/dbms_xmldom.sql.in        | 13 +++++
 contrib/dbms_xmldom/dbms_xmldom_public.sql.in |  1 +
 3 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/contrib/dbms_xmldom/dbms_xmldom.c b/contrib/dbms_xmldom/dbms_xmldom.c
index ed49245b0cb..a297ddca6d3 100644
--- a/contrib/dbms_xmldom/dbms_xmldom.c
+++ b/contrib/dbms_xmldom/dbms_xmldom.c
@@ -42,6 +42,7 @@ PG_FUNCTION_INFO_V1(dbms_xmldom_free_document);
 PG_FUNCTION_INFO_V1(dbms_xmldom_set_version);
 PG_FUNCTION_INFO_V1(dbms_xmldom_get_nodename);
 PG_FUNCTION_INFO_V1(dbms_xmldom_get_nodevalue);
+PG_FUNCTION_INFO_V1(dbms_xmldom_set_nodevalue);
 PG_FUNCTION_INFO_V1(dbms_xmldom_get_firstchild);
 PG_FUNCTION_INFO_V1(dbms_xmldom_get_childnodes);
 PG_FUNCTION_INFO_V1(dbms_xmldom_get_nodelistlength);
@@ -49,7 +50,6 @@ PG_FUNCTION_INFO_V1(dbms_xmldom_get_nodelistitem);
 PG_FUNCTION_INFO_V1(dbms_xmldom_make_element);
 PG_FUNCTION_INFO_V1(dbms_xmldom_replace_child);
 PG_FUNCTION_INFO_V1(dbms_xmldom_remove_child);
-PG_FUNCTION_INFO_V1(dbms_xmldom_set_node_value);
 
 
 /* Function Declarations */
@@ -1287,6 +1287,62 @@ dbms_xmldom_get_nodevalue(PG_FUNCTION_ARGS)
 	PG_RETURN_VARCHAR_P(cstring_to_text((char *) nodevalue));
 }
 
+/*
+ * dbms_xmldom_set_nodevalue
+ *
+ * Implements the functionality of dbms_xmldom.setNodeValue.
+ * sets the value to DOMNode
+ */
+Datum
+dbms_xmldom_set_nodevalue(PG_FUNCTION_ARGS)
+{
+	char		docHashKey[HASHKEYLEN];
+	uint32		docid = 0;
+	uint64		nodeid = 0;
+	DocInfoPtr	docInfo = NULL;
+	DocNodeInfoPtr nodeInfo = NULL;
+	char	   *nodevalue = NULL;
+	char       *nodevaluenull = NULL;
+
+	/* If node is NULL, then return. */
+	if (PG_ARGISNULL(0))
+		PG_RETURN_NULL();
+
+	if (PG_ARGISNULL(1) || strlen(text_to_cstring(PG_GETARG_TEXT_P(1))) == 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("invalid value for parameter \"%s\"", "tagName")));
+
+	nodevalue = text_to_cstring(PG_GETARG_TEXT_P(1));
+
+	memcpy(docHashKey, VARDATA_ANY(PG_GETARG_TEXT_P(0)), HASHKEYLEN);
+	extract_ids(docHashKey, &docid, &nodeid);
+
+	docInfo = getDocInfo(docid);
+	if (!docInfo)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 err_redwood_sqlcode(-31181),
+				 errmsg("invalid value for parameter \"%s\"", "n")));
+
+	nodeInfo =
+		(DocNodeInfoPtr) hash_search(docInfo->nodeInfo,
+									 &nodeid,
+									 HASH_FIND,
+									 NULL);
+
+	Assert(nodeInfo && nodeInfo->node);
+
+	/* Now set new vaule. */
+//	xmlNodeSetContent((xmlNodePtr) nodeInfo->node, (const xmlChar *) nodevaluenull);
+//	xmlNodeAddContent((xmlNodePtr) nodeInfo->node, (const xmlChar *) nodevalue);
+
+	xmlNodeSetName((xmlNodePtr) nodeInfo->node, (const xmlChar *) nodevalue);
+//	xmlNodeSetContent((xmlNodePtr) nodeInfo->node, (const xmlChar *) nodevalue);
+
+	PG_RETURN_TEXT_P(cstring_to_text_with_len(docHashKey, HASHKEYLEN));
+}
+
 /*
  * dbms_xmldom_get_firstchild
  *
diff --git a/contrib/dbms_xmldom/dbms_xmldom.sql.in b/contrib/dbms_xmldom/dbms_xmldom.sql.in
index 2236612d754..2eae94ec656 100644
--- a/contrib/dbms_xmldom/dbms_xmldom.sql.in
+++ b/contrib/dbms_xmldom/dbms_xmldom.sql.in
@@ -65,6 +65,10 @@ CREATE FUNCTION dbms_xmldom_getNodeValue(nodeid RAW) RETURNS VARCHAR2
 AS '$libdir/dbms_xmldom', 'dbms_xmldom_get_nodevalue'
 LANGUAGE C IMMUTABLE PARALLEL SAFE;
 
+CREATE FUNCTION dbms_xmldom_setNodeValue(nodeid RAW, name IN VARCHAR2) RETURNS RAW
+AS '$libdir/dbms_xmldom', 'dbms_xmldom_set_nodevalue'
+LANGUAGE C IMMUTABLE PARALLEL SAFE;
+
 CREATE FUNCTION dbms_xmldom_getFirstChild(nodeid RAW) RETURNS RAW
 AS '$libdir/dbms_xmldom', 'dbms_xmldom_get_firstchild'
 LANGUAGE C IMMUTABLE PARALLEL SAFE;
@@ -145,6 +149,14 @@ CREATE OR REPLACE PACKAGE BODY dbms_xmldom IS
 		return dbms_xmldom_getNodeValue(n.id);
 	END;
 
+	FUNCTION setNodeValue(n domnode, name IN VARCHAR2) RETURN DOMNode SET search_path = pg_catalog, pg_temp IS
+	DECLARE
+		node DOMNode;
+	BEGIN
+		n.id = dbms_xmldom_setNodeValue(n.id, name);
+		return node;
+	END;
+
 	FUNCTION getFirstChild(n DOMNode) RETURN DOMNode SET search_path = pg_catalog, pg_temp IS
 	DECLARE
 		node DOMNode;
@@ -199,6 +211,7 @@ CREATE OR REPLACE PACKAGE BODY dbms_xmldom IS
         return node;
     END;
 
+
 	FUNCTION createElement(doc DOMDocument, tagName IN VARCHAR2) RETURN DOMElement SET search_path = pg_catalog, pg_temp IS
 	DECLARE
 		node DOMElement;
diff --git a/contrib/dbms_xmldom/dbms_xmldom_public.sql.in b/contrib/dbms_xmldom/dbms_xmldom_public.sql.in
index b7b1686e1fe..8fd2463394d 100644
--- a/contrib/dbms_xmldom/dbms_xmldom_public.sql.in
+++ b/contrib/dbms_xmldom/dbms_xmldom_public.sql.in
@@ -32,6 +32,7 @@ CREATE OR REPLACE PACKAGE dbms_xmldom AUTHID CURRENT_USER AS
 
 	FUNCTION getNodeName(n DOMNode) RETURN VARCHAR2;
 	FUNCTION getNodeValue(n domnode) RETURN VARCHAR2;
+	FUNCTION setNodeValue(n domnode, name IN VARCHAR2) RETURN DOMNode;
 	FUNCTION getFirstChild(n DOMNode) RETURN DOMNode;
 	FUNCTION getChildNodes(n DOMNode) RETURN DOMNodeList;
 	FUNCTION appendChild(n DOMNode, newChild IN DOMNode) RETURN DOMNode;
-- 
2.39.3

