{"id":15566,"date":"2024-04-05T09:33:32","date_gmt":"2024-04-05T16:33:32","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=15566"},"modified":"2025-07-08T09:15:58","modified_gmt":"2025-07-08T16:15:58","slug":"improved-debuggability-for-sql-user-defined-functions","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/improved-debuggability-for-sql-user-defined-functions\/","title":{"rendered":"Mejora de la depuraci\u00f3n de funciones SQL++ definidas por el usuario"},"content":{"rendered":"<p><span style=\"font-weight: 400;\"><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/userfun.html\">Funciones definidas por el usuario (UDF)<\/a> son una caracter\u00edstica muy \u00fatil soportada en SQL++.\u00a0<\/span><span style=\"font-weight: 400;\">Couchbase 7.6 introduce mejoras que permiten una mayor depuraci\u00f3n y visibilidad en la ejecuci\u00f3n de UDF.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Este blog explorar\u00e1 dos nuevas caracter\u00edsticas de Couchbase 7.6 en el mundo de las UDFs.<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Perfilado de sentencias SQL++ ejecutadas en UDFs JavaScript<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">EXPLAIN FUNCTION para acceder a planes de consulta de sentencias SQL++ dentro de UDFs<\/span><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">Los ejemplos de este post requieren el <a href=\"https:\/\/docs.couchbase.com\/server\/current\/manage\/manage-settings\/install-sample-buckets.html\">conjunto de datos de muestras de viajes<\/a> a instalar.<\/span><\/p>\n<h2>Creaci\u00f3n de perfiles de SQL++ ejecutado en UDF de JavaScript<\/h2>\n<p><span style=\"font-weight: 400;\">El perfilado de consultas es una caracter\u00edstica de depuraci\u00f3n que ofrece SQL++.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Cuando se activa la creaci\u00f3n de perfiles para la ejecuci\u00f3n de una sentencia, el resultado de la petici\u00f3n incluye un \u00e1rbol de ejecuci\u00f3n detallado con el tiempo y las m\u00e9tricas de cada paso de la ejecuci\u00f3n de la sentencia. Adem\u00e1s de la informaci\u00f3n de perfiles que se devuelve en los resultados de la sentencia, tambi\u00e9n se puede acceder a ella para la petici\u00f3n en el archivo <em>sistema:solicitudes_activas<\/em> y <em>sistema:solicitudes_realizadas<\/em> espacios de claves del sistema.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">He aqu\u00ed un post que <a href=\"https:\/\/www.couchbase.com\/blog\/es\/optimize-n1ql-performance-using-request-profiling\/\">profundiza en el perfilado de las peticiones<\/a>.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">En Couchbase 7.0, se incluy\u00f3 la creaci\u00f3n de perfiles para subconsultas, incluida la creaci\u00f3n de perfiles de subconsultas de <em>UDFs en l\u00ednea<\/em>.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Sin embargo, con las nuevas caracter\u00edsticas de Couchbase 7.6, la creaci\u00f3n de perfiles se ampli\u00f3 a las sentencias SQL++ dentro de <em>UDF de JavaScript<\/em>.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">En versiones anteriores, para perfilar sentencias dentro de una UDF JavaScript, el usuario deb\u00eda abrir la definici\u00f3n de la funci\u00f3n, ejecutar individualmente cada sentencia dentro de la UDF y recopilar sus perfiles. Este paso adicional ya no ser\u00e1 necesario en la versi\u00f3n 7.6.0.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Ahora, cuando se habilita la creaci\u00f3n de perfiles, si la sentencia contiene la ejecuci\u00f3n de una UDF JavaScript, tambi\u00e9n se recopilar\u00e1n los perfiles de todas las sentencias SQL++ ejecutadas en la UDF. Y esta informaci\u00f3n de perfiles relacionada con UDF estar\u00e1 disponible en la salida de la petici\u00f3n, <em>sistema:solicitudes_activas<\/em> y <em>sistema:solicitudes_realizadas<\/em> del sistema.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Ejemplo 1:<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Crear una UDF JavaScript <em>js1<\/em> en una biblioteca mundial <em>lib1<\/em>\u00a0a trav\u00e9s del punto final REST o de la interfaz de usuario.<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\">function js1() {\r\n\r\n\u00a0\u00a0\u00a0\u00a0var query = SELECT * FROM default:`travel-sample`.inventory.airline LIMIT 1;\r\n\r\n\u00a0\u00a0\u00a0\u00a0var res = [];\r\n\u00a0\u00a0\u00a0\u00a0for (const row of query) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0res.push(row);\r\n\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0\u00a0\u00a0query.close()\r\n\r\n\u00a0\u00a0\u00a0\u00a0return res;\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Crear la funci\u00f3n SQL++ correspondiente:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">CREATE FUNCTION js1() LANGUAGE JAVASCRIPT AS \"js1\" AT \"lib1\";<\/pre>\n<p><span style=\"font-weight: 400;\"> Ejecuta la UDF con el perfil activado:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">EXECUTE FUNCTION js1();\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">En el <\/span><b>perfil<\/b><span style=\"font-weight: 400;\"> de la respuesta devuelta, el campo <\/span><b>executionTimings<\/b><span style=\"font-weight: 400;\"> contiene un campo <\/span><b>~declaracionesudf<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><b>~declaracionesudf<\/b><span style=\"font-weight: 400;\">\u00a0es una matriz de informaci\u00f3n de perfiles que contiene una entrada por cada sentencia SQL++ dentro de la UDF JavaScript.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Cada entrada dentro del <\/span><b>~declaracionesudf<\/b><span style=\"font-weight: 400;\"> contiene:<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\"><b>executionTimings <\/b>&#8211; <span style=\"font-weight: 400;\">El \u00e1rbol de ejecuci\u00f3n de la sentencia. Contiene informaci\u00f3n sobre m\u00e9tricas y tiempos de cada paso de la ejecuci\u00f3n de la sentencia.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>declaraci\u00f3n<\/b> &#8211; <span style=\"font-weight: 400;\">La cadena de la declaraci\u00f3n.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>funci\u00f3n<\/b> &#8211; <span style=\"font-weight: 400;\">El nombre de la funci\u00f3n donde se ejecut\u00f3 la sentencia. Esto es \u00fatil para identificar la UDF que ejecut\u00f3 la sentencia cuando hay ejecuciones UDF anidadas.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<pre class=\"lang:js decode:true\">{\r\n  \"requestID\": \"2c5576b5-f01d-445f-a35b-2213c606f394\",\r\n  \"signature\": null,\r\n  \"results\": [\r\n    [\r\n      {\r\n        \"airline\": {\r\n          \"callsign\": \"MILE-AIR\",\r\n          \"country\": \"United States\",\r\n          \"iata\": \"Q5\",\r\n          \"icao\": \"MLA\",\r\n          \"id\": 10,\r\n          \"name\": \"40-Mile Air\",\r\n          \"type\": \"airline\"\r\n        }\r\n      }\r\n    ]\r\n  ],\r\n  \"status\": \"success\",\r\n  \"metrics\": {\r\n    \"elapsedTime\": \"20.757583ms\",\r\n    \"executionTime\": \"20.636792ms\",\r\n    \"resultCount\": 1,\r\n    \"resultSize\": 310,\r\n    \"serviceLoad\": 2\r\n  },\r\n  \"profile\": {\r\n    \"phaseTimes\": {\r\n      \"authorize\": \"12.835\u00b5s\",\r\n      \"fetch\": \"374.667\u00b5s\",\r\n      \"instantiate\": \"27.75\u00b5s\",\r\n      \"parse\": \"251.708\u00b5s\",\r\n      \"plan\": \"9.125\u00b5s\",\r\n      \"primaryScan\": \"813.249\u00b5s\",\r\n      \"primaryScan.GSI\": \"813.249\u00b5s\",\r\n      \"project\": \"5.541\u00b5s\",\r\n      \"run\": \"27.925833ms\",\r\n      \"stream\": \"26.375\u00b5s\"\r\n    },\r\n    \"phaseCounts\": {\r\n      \"fetch\": 1,\r\n      \"primaryScan\": 1,\r\n      \"primaryScan.GSI\": 1\r\n    },\r\n    \"phaseOperators\": {\r\n      \"authorize\": 2,\r\n      \"fetch\": 1,\r\n      \"primaryScan\": 1,\r\n      \"primaryScan.GSI\": 1,\r\n      \"project\": 1,\r\n      \"stream\": 1\r\n    },\r\n    \"cpuTime\": \"468.626\u00b5s\",\r\n    \"requestTime\": \"2023-12-04T20:30:00.369+05:30\",\r\n    \"servicingHost\": \"127.0.0.1:8091\",\r\n    \"executionTimings\": {\r\n      \"#operator\": \"Authorize\",\r\n      \"#planPreparedTime\": \"2023-12-04T20:30:00.369+05:30\",\r\n      \"#stats\": {\r\n        \"#phaseSwitches\": 4,\r\n        \"execTime\": \"1.918\u00b5s\",\r\n        \"servTime\": \"1.125\u00b5s\"\r\n      },\r\n      \"privileges\": {\r\n        \"List\": []\r\n      },\r\n      \"~child\": {\r\n        \"#operator\": \"Sequence\",\r\n        \"#stats\": {\r\n          \"#phaseSwitches\": 2,\r\n          \"execTime\": \"2.208\u00b5s\"\r\n        },\r\n        \"~children\": [\r\n          {\r\n            \"#operator\": \"ExecuteFunction\",\r\n            \"#stats\": {\r\n              \"#itemsOut\": 1,\r\n              \"#phaseSwitches\": 4,\r\n              \"execTime\": \"22.375\u00b5s\",\r\n              \"kernTime\": \"20.271708ms\"\r\n            },\r\n            \"identity\": {\r\n              \"name\": \"js1\",\r\n              \"namespace\": \"default\",\r\n              \"type\": \"global\"\r\n            }\r\n          },\r\n          {\r\n            \"#operator\": \"Stream\",\r\n            \"#stats\": {\r\n              \"#itemsIn\": 1,\r\n              \"#itemsOut\": 1,\r\n              \"#phaseSwitches\": 2,\r\n              \"execTime\": \"26.375\u00b5s\"\r\n            },\r\n            \"serializable\": true\r\n          }\r\n        ]\r\n      },\r\n      \"~udfStatements\": [\r\n        {\r\n          \"executionTimings\": {\r\n            \"#operator\": \"Authorize\",\r\n            \"#stats\": {\r\n              \"#phaseSwitches\": 4,\r\n              \"execTime\": \"2.626\u00b5s\",\r\n              \"servTime\": \"7.166\u00b5s\"\r\n            },\r\n            \"privileges\": {\r\n              \"List\": [\r\n                {\r\n                  \"Priv\": 7,\r\n                  \"Props\": 0,\r\n                  \"Target\": \"default:travel-sample.inventory.airline\"\r\n                }\r\n              ]\r\n            },\r\n            \"~child\": {\r\n              \"#operator\": \"Sequence\",\r\n              \"#stats\": {\r\n                \"#phaseSwitches\": 2,\r\n                \"execTime\": \"4.375\u00b5s\"\r\n              },\r\n              \"~children\": [\r\n                {\r\n                  \"#operator\": \"PrimaryScan3\",\r\n                  \"#stats\": {\r\n                    \"#itemsIn\": 1,\r\n                    \"#itemsOut\": 1,\r\n                    \"#phaseSwitches\": 7,\r\n                    \"execTime\": \"22.082\u00b5s\",\r\n                    \"kernTime\": \"1.584\u00b5s\",\r\n                    \"servTime\": \"791.167\u00b5s\"\r\n                  },\r\n                  \"bucket\": \"travel-sample\",\r\n                  \"index\": \"def_inventory_airline_primary\",\r\n                  \"index_projection\": {\r\n                    \"primary_key\": true\r\n                  },\r\n                  \"keyspace\": \"airline\",\r\n                  \"limit\": \"1\",\r\n                  \"namespace\": \"default\",\r\n                  \"optimizer_estimates\": {\r\n                    \"cardinality\": 187,\r\n                    \"cost\": 45.28617059639748,\r\n                    \"fr_cost\": 12.1780009122802,\r\n                    \"size\": 12\r\n                  },\r\n                  \"scope\": \"inventory\",\r\n                  \"using\": \"gsi\"\r\n                },\r\n                {\r\n                  \"#operator\": \"Fetch\",\r\n                  \"#stats\": {\r\n                    \"#itemsIn\": 1,\r\n                    \"#itemsOut\": 1,\r\n                    \"#phaseSwitches\": 10,\r\n                    \"execTime\": \"18.376\u00b5s\",\r\n                    \"kernTime\": \"797.542\u00b5s\",\r\n                    \"servTime\": \"356.291\u00b5s\"\r\n                  },\r\n                  \"bucket\": \"travel-sample\",\r\n                  \"keyspace\": \"airline\",\r\n                  \"namespace\": \"default\",\r\n                  \"optimizer_estimates\": {\r\n                    \"cardinality\": 187,\r\n                    \"cost\": 192.01699202888378,\r\n                    \"fr_cost\": 24.89848658838975,\r\n                    \"size\": 204\r\n                  },\r\n                  \"scope\": \"inventory\"\r\n                },\r\n                {\r\n                  \"#operator\": \"InitialProject\",\r\n                  \"#stats\": {\r\n                    \"#itemsIn\": 1,\r\n                    \"#itemsOut\": 1,\r\n                    \"#phaseSwitches\": 7,\r\n                    \"execTime\": \"5.541\u00b5s\",\r\n                    \"kernTime\": \"1.1795ms\"\r\n                  },\r\n                  \"discard_original\": true,\r\n                  \"optimizer_estimates\": {\r\n                    \"cardinality\": 187,\r\n                    \"cost\": 194.6878862611588,\r\n                    \"fr_cost\": 24.912769445246838,\r\n                    \"size\": 204\r\n                  },\r\n                  \"preserve_order\": true,\r\n                  \"result_terms\": [\r\n                    {\r\n                      \"expr\": \"self\",\r\n                      \"star\": true\r\n                    }\r\n                  ]\r\n                },\r\n                {\r\n                  \"#operator\": \"Limit\",\r\n                  \"#stats\": {\r\n                    \"#itemsIn\": 1,\r\n                    \"#itemsOut\": 1,\r\n                    \"#phaseSwitches\": 4,\r\n                    \"execTime\": \"6.25\u00b5s\",\r\n                    \"kernTime\": \"333ns\"\r\n                  },\r\n                  \"expr\": \"1\",\r\n                  \"optimizer_estimates\": {\r\n                    \"cardinality\": 1,\r\n                    \"cost\": 24.927052302103924,\r\n                    \"fr_cost\": 24.927052302103924,\r\n                    \"size\": 204\r\n                  }\r\n                },\r\n                {\r\n                  \"#operator\": \"Receive\",\r\n                  \"#stats\": {\r\n                    \"#phaseSwitches\": 3,\r\n                    \"execTime\": \"10.324833ms\",\r\n                    \"kernTime\": \"792ns\",\r\n                    \"state\": \"running\"\r\n                  }\r\n                }\r\n              ]\r\n            }\r\n          },\r\n          \"statement\": \"SELECT * FROM default:`travel-sample`.inventory.airline LIMIT 1;\",\r\n          \"function\": \"default:js1\"\r\n        }\r\n      ],\r\n      \"~versions\": [\r\n        \"7.6.0-N1QL\",\r\n        \"7.6.0-1847-enterprise\"\r\n      ]\r\n    }\r\n  }\r\n}<\/pre>\n<h2>Planes de consulta con EXPLAIN FUNCTION<\/h2>\n<p><span style=\"font-weight: 400;\">SQL++ ofrece otra maravillosa capacidad para acceder al plan de una sentencia con la sentencia EXPLAIN. Pero la sentencia EXPLAIN no se extiende a los planes de sentencias dentro de UDFs-ni Inline ni JavaScript UDFs.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">En versiones anteriores, para analizar los planes de consulta de SQL++ dentro de una UDF era necesario que el usuario abriera la definici\u00f3n de la funci\u00f3n y ejecutara individualmente un EXPLAIN en todas las sentencias de la UDF.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Estos pasos adicionales se reducen al m\u00ednimo en Couchbase 7.6 con la introducci\u00f3n de una nueva declaraci\u00f3n.<em>EXPLICAR LA FUNCI\u00d3N<\/em>. Esta sentencia hace exactamente lo mismo que EXPLAIN, pero para sentencias SQL++ dentro de una UDF.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Exploremos c\u00f3mo utilizar la sentencia EXPLAIN FUNCTION.<\/span><\/p>\n<h3>Sintaxis<\/h3>\n<pre class=\"lang:default decode:true\">explain_function ::= 'EXPLAIN' 'FUNCTION' function<\/pre>\n<p><span style=\"font-weight: 400;\">Toma, <em>funci\u00f3n<\/em>\u00a0se refiere al nombre de la funci\u00f3n.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Para obtener informaci\u00f3n m\u00e1s detallada sobre la sintaxis, consulte la documentaci\u00f3n.<\/span><\/p>\n<h3>Requisitos previos<\/h3>\n<p><span style=\"font-weight: 400;\">Para ejecutar EXPLAIN FUNCTION en una UDF, el usuario debe tener suficiente <a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/userfun.html#rbac-privileges\">Permisos RBAC<\/a> a <\/span><i><span style=\"font-weight: 400;\">ejecutar<\/span><\/i><span style=\"font-weight: 400;\"> la funci\u00f3n.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">El usuario tambi\u00e9n debe tener los permisos RBAC necesarios para ejecutar las sentencias SQL++ dentro del cuerpo de la funci\u00f3n UDF.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Aqu\u00ed est\u00e1n los <a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/security\/roles.html\">roles soportados en Couchbase<\/a>.<\/span><\/p>\n<h3>UDF en l\u00ednea<\/h3>\n<p><span style=\"font-weight: 400;\">EXPLAIN FUNCTION en una UDF en l\u00ednea devolver\u00e1 los planes de consulta de todas las subconsultas dentro de su definici\u00f3n.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Ejemplo 2 - EXPLAIN FUNCTION en una funci\u00f3n en l\u00ednea<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Cree una UDF en l\u00ednea y ejecute EXPLAIN FUNCTION en ella:<\/span><\/p>\n<pre class=\"lang:default decode:true\">CREATE FUNCTION inline1() { (\u00a0\u00a0\r\n\u00a0 SELECT * FROM default:`travel-sample`.inventory.airport WHERE city = \"Zachar Bay\"\r\n) };<\/pre>\n<pre class=\"lang:default decode:true\">EXPLAIN FUNCTION inline1();<\/pre>\n<p><span style=\"font-weight: 400;\">Los resultados de la declaraci\u00f3n anterior contendr\u00e1n:<\/span><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\"><b>funci\u00f3n<\/b><span style=\"font-weight: 400;\">\u00a0- El nombre de la funci\u00f3n sobre la que se ha ejecutado EXPLAIN FUNCTION.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>planos<\/b><span style=\"font-weight: 400;\">\u00a0- Una matriz de informaci\u00f3n del plan que contiene una entrada para cada subconsulta dentro de la UDF en l\u00ednea.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre class=\"lang:js decode:true\">{\r\n        \"function\": \"default:inline1\",\r\n        \"plans\": [\r\n            {\r\n                \"cardinality\": 1.1176470588235294,\r\n                \"cost\": 25.117642854609013,\r\n                \"plan\": {\r\n                    \"#operator\": \"Sequence\",\r\n                    \"~children\": [\r\n                        {\r\n                            \"#operator\": \"IndexScan3\",\r\n                            \"bucket\": \"travel-sample\",\r\n                            \"index\": \"def_inventory_airport_city\",\r\n                            \"index_id\": \"2605c88c115dd3a2\",\r\n                            \"index_projection\": {\r\n                                \"primary_key\": true\r\n                            },\r\n                            \"keyspace\": \"airport\",\r\n                            \"namespace\": \"default\",\r\n                            \"optimizer_estimates\": {\r\n                                \"cardinality\": 1.1176470588235294,\r\n                                \"cost\": 12.200561852726496,\r\n                                \"fr_cost\": 12.179450078755286,\r\n                                \"size\": 12\r\n                            },\r\n                            \"scope\": \"inventory\",\r\n                            \"spans\": [\r\n                                {\r\n                                    \"exact\": true,\r\n                                    \"range\": [\r\n                                        {\r\n                                            \"high\": \"\\\\\"Zachar Bay\\\\\"\",\r\n                                            \"inclusion\": 3,\r\n                                            \"index_key\": \"`city`\",\r\n                                            \"low\": \"\\\\\"Zachar Bay\\\\\"\"\r\n                                        }\r\n                                    ]\r\n                                }\r\n                            ],\r\n                            \"using\": \"gsi\"\r\n                        },\r\n                        {\r\n                            \"#operator\": \"Fetch\",\r\n                            \"bucket\": \"travel-sample\",\r\n                            \"keyspace\": \"airport\",\r\n                            \"namespace\": \"default\",\r\n                            \"optimizer_estimates\": {\r\n                                \"cardinality\": 1.1176470588235294,\r\n                                \"cost\": 25.082370508382763,\r\n                                \"fr_cost\": 24.96843677065826,\r\n                                \"size\": 249\r\n                            },\r\n                            \"scope\": \"inventory\"\r\n                        },\r\n                        {\r\n                            \"#operator\": \"Parallel\",\r\n                            \"~child\": {\r\n                                \"#operator\": \"Sequence\",\r\n                                \"~children\": [\r\n                                    {\r\n                                        \"#operator\": \"Filter\",\r\n                                        \"condition\": \"((`airport`.`city`) = \\\\\"Zachar Bay\\\\\")\",\r\n                                        \"optimizer_estimates\": {\r\n                                            \"cardinality\": 1.1176470588235294,\r\n                                            \"cost\": 25.100006681495888,\r\n                                            \"fr_cost\": 24.98421650449632,\r\n                                            \"size\": 249\r\n                                        }\r\n                                    },\r\n                                    {\r\n                                        \"#operator\": \"InitialProject\",\r\n                                        \"discard_original\": true,\r\n                                        \"optimizer_estimates\": {\r\n                                            \"cardinality\": 1.1176470588235294,\r\n                                            \"cost\": 25.117642854609013,\r\n                                            \"fr_cost\": 24.99999623833438,\r\n                                            \"size\": 249\r\n                                        },\r\n                                        \"result_terms\": [\r\n                                            {\r\n                                                \"expr\": \"self\",\r\n                                                \"star\": true\r\n                                            }\r\n                                        ]\r\n                                    }\r\n                                ]\r\n                            }\r\n                        }\r\n                    ]\r\n                },\r\n                \"statement\": \"select self.* from `default`:`travel-sample`.`inventory`.`airport` where ((`airport`.`city`) = \\\\\"Zachar Bay\\\\\")\"\r\n            }\r\n        ]\r\n    }<\/pre>\n<h3>JavaScript UDF<\/h3>\n<p><span style=\"font-weight: 400;\">Las sentencias SQL++ dentro de las UDFs de JavaScript pueden ser de dos tipos y EXPLAIN FUNCTION funciona de forma diferente bas\u00e1ndose en la forma en que se llama a la sentencia SQL++.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Aqu\u00ed est\u00e1 la referencia documental a <a href=\"https:\/\/docs.couchbase.com\/server\/current\/javascript-udfs\/calling-n1ql-from-javascript.html\">Llamada a SQL++ en funciones JavaScript<\/a>.<\/span><\/p>\n<h4>SQL++ integrado<\/h4>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">SQL++ incrustado est\u00e1 \"incrustado\" en el cuerpo de la funci\u00f3n y su detecci\u00f3n es gestionada por el transpilador de JavaScript.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">EXPLAIN FUNCTION puede devolver planes de consulta para sentencias SQL++ incrustadas.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4><\/h4>\n<h4>\u00a0SQL++ ejecutado por la llamada a la funci\u00f3n N1QL()<\/h4>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">SQL++ tambi\u00e9n puede ejecutarse pasando una sentencia en forma de cadena como argumento a la funci\u00f3n N1QL().<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Cuando se analiza la funci\u00f3n para posibles sentencias SQL++ sobre las que ejecutar EXPLAIN, es dif\u00edcil obtener la cadena din\u00e1mica en el argumento de la funci\u00f3n. Esto s\u00f3lo se puede resolver de forma fiable en tiempo de ejecuci\u00f3n.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Con este razonamiento, EXPLAIN FUNCTION no devuelve los planes de consulta para sentencias SQL++ ejecutadas mediante llamadas a N1QL(). Sino que devuelve los n\u00fameros de l\u00ednea donde se han realizado las llamadas a la funci\u00f3n N1QL(). Este n\u00famero de l\u00ednea se calcula desde el principio de la definici\u00f3n de la funci\u00f3n.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">A continuaci\u00f3n, el usuario puede asignar los n\u00fameros de l\u00ednea en la definici\u00f3n real de la funci\u00f3n e investigar m\u00e1s a fondo.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3><span style=\"font-weight: 400;\">Ejemplo 3 - EXPLAIN FUNCTION en una funci\u00f3n JavaScript externa<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Crear una UDF JavaScript <em>js2<\/em> en una biblioteca mundial <em>lib1<\/em> a trav\u00e9s del punto final REST o de la interfaz de usuario:<\/span><\/p>\n<pre class=\"lang:js decode:true\">function js2() { \r\n    \/\/ SQL++ executed by a N1QL() function call\r\n    var query1 = N1QL(\"UPDATE default:`travel-sample` SET test = 1 LIMIT 1\");\r\n    \r\n    \/\/ Embedded SQL++\r\n    var query2 = SELECT * FROM default:`travel-sample` LIMIT 1;\r\n    \r\n    var res = [];\r\n    for (const row of query2) {\r\n        res.push(row);\r\n    }\r\n    query2.close()\r\n\r\n    return res;\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400;\"> Crear la funci\u00f3n SQL++ correspondiente:<\/span><\/p>\n<pre class=\"lang:default decode:true\">CREATE FUNCTION js2() LANGUAGE JAVASCRIPT AS \"js2\" AT \"lib1\";<\/pre>\n<p><span style=\"font-weight: 400;\"> Ejecute EXPLAIN FUNCTION en la funci\u00f3n SQL++:<\/span><\/p>\n<pre class=\"lang:default decode:true\">EXPLAIN FUNCTION js2;<\/pre>\n<p><span style=\"font-weight: 400;\">Los resultados de la declaraci\u00f3n anterior contendr\u00e1n:<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li style=\"font-weight: 400;\"><b>funci\u00f3n<\/b><span style=\"font-weight: 400;\">\u00a0- El nombre de la funci\u00f3n sobre la que se ha ejecutado EXPLAIN FUNCTION.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>n\u00fameros_de_l\u00ednea<\/b><span style=\"font-weight: 400;\">\u00a0- Una matriz de n\u00fameros de l\u00ednea calculados desde el principio de la definici\u00f3n de la funci\u00f3n JavaScript donde hay llamadas a la funci\u00f3n N1QL().<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>planos<\/b><span style=\"font-weight: 400;\">\u00a0- Una matriz de informaci\u00f3n del plan que contiene una entrada por cada <\/span><i><span style=\"font-weight: 400;\">incrustado<\/span><\/i><span style=\"font-weight: 400;\"> SQL++ dentro de la UDF JavaScript.<\/span><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<pre class=\"lang:js decode:true\">{\r\n  \"function\": \"default:js2\",\r\n  \"line_numbers\": [\r\n    4\r\n  ],\r\n  \"plans\": [\r\n    {\r\n      \"cardinality\": 1,\r\n      \"cost\": 25.51560885530435,\r\n      \"plan\": {\r\n        \"#operator\": \"Authorize\",\r\n        \"privileges\": {\r\n          \"List\": [\r\n            {\r\n              \"Target\": \"default:travel-sample\",\r\n              \"Priv\": 7,\r\n              \"Props\": 0\r\n            }\r\n          ]\r\n        },\r\n        \"~child\": {\r\n          \"#operator\": \"Sequence\",\r\n          \"~children\": [\r\n            {\r\n              \"#operator\": \"Sequence\",\r\n              \"~children\": [\r\n                {\r\n                  \"#operator\": \"Sequence\",\r\n                  \"~children\": [\r\n                    {\r\n                      \"#operator\": \"PrimaryScan3\",\r\n                      \"index\": \"def_primary\",\r\n                      \"index_projection\": {\r\n                        \"primary_key\": true\r\n                      },\r\n                      \"keyspace\": \"travel-sample\",\r\n                      \"limit\": \"1\",\r\n                      \"namespace\": \"default\",\r\n                      \"optimizer_estimates\": {\r\n                        \"cardinality\": 31591,\r\n                        \"cost\": 5402.279801258844,\r\n                        \"fr_cost\": 12.170627071041082,\r\n                        \"size\": 11\r\n                      },\r\n                      \"using\": \"gsi\"\r\n                    },\r\n                    {\r\n                      \"#operator\": \"Fetch\",\r\n                      \"keyspace\": \"travel-sample\",\r\n                      \"namespace\": \"default\",\r\n                      \"optimizer_estimates\": {\r\n                        \"cardinality\": 31591,\r\n                        \"cost\": 46269.39474997121,\r\n                        \"fr_cost\": 25.46387878667884,\r\n                        \"size\": 669\r\n                      }\r\n                    },\r\n                    {\r\n                      \"#operator\": \"Parallel\",\r\n                      \"~child\": {\r\n                        \"#operator\": \"Sequence\",\r\n                        \"~children\": [\r\n                          {\r\n                            \"#operator\": \"InitialProject\",\r\n                            \"discard_original\": true,\r\n                            \"optimizer_estimates\": {\r\n                              \"cardinality\": 31591,\r\n                              \"cost\": 47086.49704894546,\r\n                              \"fr_cost\": 25.489743820991595,\r\n                              \"size\": 669\r\n                            },\r\n                            \"preserve_order\": true,\r\n                            \"result_terms\": [\r\n                              {\r\n                                \"expr\": \"self\",\r\n                                \"star\": true\r\n                              }\r\n                            ]\r\n                          }\r\n                        ]\r\n                      }\r\n                    }\r\n                  ]\r\n                },\r\n                {\r\n                  \"#operator\": \"Limit\",\r\n                  \"expr\": \"1\",\r\n                  \"optimizer_estimates\": {\r\n                    \"cardinality\": 1,\r\n                    \"cost\": 25.51560885530435,\r\n                    \"fr_cost\": 25.51560885530435,\r\n                    \"size\": 669\r\n                  }\r\n                }\r\n              ]\r\n            },\r\n            {\r\n              \"#operator\": \"Stream\",\r\n              \"optimizer_estimates\": {\r\n                \"cardinality\": 1,\r\n                \"cost\": 25.51560885530435,\r\n                \"fr_cost\": 25.51560885530435,\r\n                \"size\": 669\r\n              },\r\n              \"serializable\": true\r\n            }\r\n          ]\r\n        }\r\n      },\r\n      \"statement\": \"SELECT * FROM default:`travel-sample` LIMIT 1 ;\"\r\n    }\r\n  ]\r\n}<\/pre>\n<h3>Restricciones<\/h3>\n<p><span style=\"font-weight: 400;\">Si la funci\u00f3n N1QL() ha sido aliasada en una definici\u00f3n de funci\u00f3n JavaScript, EXPLAIN FUNCTION no podr\u00e1 devolver los n\u00fameros de l\u00ednea donde esta funci\u00f3n aliasada fue llamada. Por ejemplo:<\/span><\/p>\n<pre class=\"lang:js decode:true\">function js3() {\r\n  var alias = N1QL;\r\n  var q = alias(\"SELECT 1\");\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Si la UDF contiene ejecuciones UDF anidadas, EXPLAIN FUNCTION no soporta la generaci\u00f3n de planes de consulta de sentencias SQL++ dentro de estas UDFs anidadas.<\/span><\/p>\n<h2>Resumen<\/h2>\n<p>Couchbase 7.6 introduce nuevas caracter\u00edsticas para la depuraci\u00f3n UDF que ayudar\u00e1n a los usuarios a echar un vistazo a la ejecuci\u00f3n UDF f\u00e1cilmente.<\/p>\n<p>Consulte los siguientes enlaces de documentaci\u00f3n para obtener m\u00e1s informaci\u00f3n, o eche un vistazo a las dem\u00e1s novedades de Couchbase 7.6:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/es\/couchbase-server-7-6-top-developer-features\/\">Caracter\u00edsticas de Couchbase Server 7.6 que encantar\u00e1n a los desarrolladores<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/userfun.html\">Funciones definidas por el usuario<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/createfunction.html#create-function-inline\"> UDFs en l\u00ednea<\/a><\/li>\n<li><span style=\"font-weight: 400;\"><a href=\"https:\/\/docs.couchbase.com\/server\/current\/javascript-udfs\/javascript-functions-with-couchbase.html\">Gu\u00eda de las UDF de JavaScript<\/a><\/span><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/createfunction.html#create-function-external\">Creaci\u00f3n de una UDF externa<\/a><\/li>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/es\/from-n1ql-to-javascript-and-back-part-1-introduction\/\">Serie de blogs sobre las UDF de JavaScript<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/explain.html\">Sentencia Couchbase SQL++ EXPLAIN<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>User-defined functions (UDFs) are a very useful feature supported in SQL++.\u00a0Couchbase 7.6 introduces improvements that allow for more debuggability and visibility into UDF execution. This blog will explore two new features in Couchbase 7.6 in the world of UDFs. Profiling [&hellip;]<\/p>","protected":false},"author":85183,"featured_media":15569,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,1816,10133,9327,1812],"tags":[9945,9949,1854,8911],"ppma_author":[9950],"class_list":["post-15566","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-couchbase-server","category-engineering","category-javascript","category-n1ql-query","tag-couchbase-7-6","tag-debug","tag-profiling","tag-udf"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.2 (Yoast SEO v26.2) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Debuggability for SQL++ UDFs Improved in Couchbase 7.6<\/title>\n<meta name=\"description\" content=\"Couchbase 7.6 introduces new features to debug user-defined functions (UDFs) which will help users peek into execution easily. Learn about them here.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/es\/improved-debuggability-for-sql-user-defined-functions\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Improved Debuggability for SQL++ User-Defined Functions\" \/>\n<meta property=\"og:description\" content=\"Couchbase 7.6 introduces new features to debug user-defined functions (UDFs) which will help users peek into execution easily. Learn about them here.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/improved-debuggability-for-sql-user-defined-functions\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-04-05T16:33:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-07-08T16:15:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/Screenshot-2024-04-05-at-10.36.07\u202fAM.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2868\" \/>\n\t<meta property=\"og:image:height\" content=\"1574\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Dhanya Gowrish, Software Engineer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Dhanya Gowrish, Software Engineer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/\"},\"author\":{\"name\":\"Dhanya Gowrish, Software Engineer\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/1515ea2da3d43fe576990a63041fbd73\"},\"headline\":\"Improved Debuggability for SQL++ User-Defined Functions\",\"datePublished\":\"2024-04-05T16:33:32+00:00\",\"dateModified\":\"2025-07-08T16:15:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/\"},\"wordCount\":1081,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/Screenshot-2024-04-05-at-10.36.07\u202fAM.png\",\"keywords\":[\"Couchbase 7.6\",\"debug\",\"profiling\",\"User Defined Function (UDF)\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Couchbase Server\",\"Engineering\",\"JavaScript\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/\",\"name\":\"Debuggability for SQL++ UDFs Improved in Couchbase 7.6\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/Screenshot-2024-04-05-at-10.36.07\u202fAM.png\",\"datePublished\":\"2024-04-05T16:33:32+00:00\",\"dateModified\":\"2025-07-08T16:15:58+00:00\",\"description\":\"Couchbase 7.6 introduces new features to debug user-defined functions (UDFs) which will help users peek into execution easily. Learn about them here.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/Screenshot-2024-04-05-at-10.36.07\u202fAM.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/Screenshot-2024-04-05-at-10.36.07\u202fAM.png\",\"width\":2868,\"height\":1574},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Improved Debuggability for SQL++ User-Defined Functions\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/1515ea2da3d43fe576990a63041fbd73\",\"name\":\"Dhanya Gowrish, Software Engineer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/e3bcefcd291385aabb0a1a9135722c59\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/dhanyagowrish-couchbase.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/dhanyagowrish-couchbase.png\",\"caption\":\"Dhanya Gowrish, Software Engineer\"},\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/dhanyagowrish\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Debuggability for SQL++ UDFs Improved in Couchbase 7.6","description":"Couchbase 7.6 introduce nuevas caracter\u00edsticas para depurar funciones definidas por el usuario (UDFs) que ayudar\u00e1n a los usuarios a echar un vistazo a la ejecuci\u00f3n f\u00e1cilmente. Inf\u00f3rmate sobre ellas aqu\u00ed.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/es\/improved-debuggability-for-sql-user-defined-functions\/","og_locale":"es_MX","og_type":"article","og_title":"Improved Debuggability for SQL++ User-Defined Functions","og_description":"Couchbase 7.6 introduces new features to debug user-defined functions (UDFs) which will help users peek into execution easily. Learn about them here.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/improved-debuggability-for-sql-user-defined-functions\/","og_site_name":"The Couchbase Blog","article_published_time":"2024-04-05T16:33:32+00:00","article_modified_time":"2025-07-08T16:15:58+00:00","og_image":[{"width":2868,"height":1574,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/Screenshot-2024-04-05-at-10.36.07\u202fAM.png","type":"image\/png"}],"author":"Dhanya Gowrish, Software Engineer","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Dhanya Gowrish, Software Engineer","Est. reading time":"5 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/"},"author":{"name":"Dhanya Gowrish, Software Engineer","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/1515ea2da3d43fe576990a63041fbd73"},"headline":"Improved Debuggability for SQL++ User-Defined Functions","datePublished":"2024-04-05T16:33:32+00:00","dateModified":"2025-07-08T16:15:58+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/"},"wordCount":1081,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/Screenshot-2024-04-05-at-10.36.07\u202fAM.png","keywords":["Couchbase 7.6","debug","profiling","User Defined Function (UDF)"],"articleSection":["Best Practices and Tutorials","Couchbase Server","Engineering","JavaScript","SQL++ \/ N1QL Query"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/","url":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/","name":"Debuggability for SQL++ UDFs Improved in Couchbase 7.6","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/Screenshot-2024-04-05-at-10.36.07\u202fAM.png","datePublished":"2024-04-05T16:33:32+00:00","dateModified":"2025-07-08T16:15:58+00:00","description":"Couchbase 7.6 introduce nuevas caracter\u00edsticas para depurar funciones definidas por el usuario (UDFs) que ayudar\u00e1n a los usuarios a echar un vistazo a la ejecuci\u00f3n f\u00e1cilmente. Inf\u00f3rmate sobre ellas aqu\u00ed.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/Screenshot-2024-04-05-at-10.36.07\u202fAM.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/Screenshot-2024-04-05-at-10.36.07\u202fAM.png","width":2868,"height":1574},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Improved Debuggability for SQL++ User-Defined Functions"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/1515ea2da3d43fe576990a63041fbd73","name":"Dhanya Gowrish, Ingeniero de Software","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/e3bcefcd291385aabb0a1a9135722c59","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/dhanyagowrish-couchbase.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/dhanyagowrish-couchbase.png","caption":"Dhanya Gowrish, Software Engineer"},"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/dhanyagowrish\/"}]}},"authors":[{"term_id":9950,"user_id":85183,"is_guest":0,"slug":"dhanyagowrish","display_name":"Dhanya Gowrish, Software Engineer","avatar_url":{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/dhanyagowrish-couchbase.png","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/04\/dhanyagowrish-couchbase.png"},"author_category":"","last_name":"Gowrish, Software Engineer","first_name":"Dhanya","job_title":"","user_url":"","description":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/15566","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/85183"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=15566"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/15566\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/15569"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=15566"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=15566"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=15566"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=15566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}