{"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\/pt\/improved-debuggability-for-sql-user-defined-functions\/","title":{"rendered":"Melhor capacidade de depura\u00e7\u00e3o para fun\u00e7\u00f5es definidas pelo usu\u00e1rio do SQL++"},"content":{"rendered":"<p><span style=\"font-weight: 400;\"><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/userfun.html\">Fun\u00e7\u00f5es definidas pelo usu\u00e1rio (UDFs)<\/a> s\u00e3o um recurso muito \u00fatil suportado no SQL++.\u00a0<\/span><span style=\"font-weight: 400;\">O Couchbase 7.6 apresenta aprimoramentos que permitem maior capacidade de depura\u00e7\u00e3o e visibilidade da execu\u00e7\u00e3o de UDFs.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Este blog explorar\u00e1 dois novos recursos do Couchbase 7.6 no mundo das 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;\">Cria\u00e7\u00e3o de perfil para instru\u00e7\u00f5es SQL++ executadas em UDFs JavaScript<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">EXPLAIN FUNCTION para acessar planos de consulta de instru\u00e7\u00f5es SQL++ em UDFs<\/span><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">Os exemplos nesta postagem requerem o <a href=\"https:\/\/docs.couchbase.com\/server\/current\/manage\/manage-settings\/install-sample-buckets.html\">conjunto de dados de amostra de viagens<\/a> a ser instalado.<\/span><\/p>\n<h2>Cria\u00e7\u00e3o de perfil do SQL++ executado em UDFs JavaScript<\/h2>\n<p><span style=\"font-weight: 400;\">A cria\u00e7\u00e3o de perfil de consulta \u00e9 um recurso de depura\u00e7\u00e3o que o SQL++ oferece.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Quando a cria\u00e7\u00e3o de perfil est\u00e1 ativada para a execu\u00e7\u00e3o de uma instru\u00e7\u00e3o, o resultado da solicita\u00e7\u00e3o inclui uma \u00e1rvore de execu\u00e7\u00e3o detalhada com o tempo e as m\u00e9tricas de cada etapa da execu\u00e7\u00e3o da instru\u00e7\u00e3o. Al\u00e9m de as informa\u00e7\u00f5es de cria\u00e7\u00e3o de perfil serem retornadas nos resultados da instru\u00e7\u00e3o, elas tamb\u00e9m podem ser acessadas para a solicita\u00e7\u00e3o na fun\u00e7\u00e3o <em>system:active_requests<\/em> e <em>system:completed_requests<\/em> espa\u00e7os de chaves do sistema.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Aqui est\u00e1 uma postagem que <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/optimize-n1ql-performance-using-request-profiling\/\">aprofunda-se na cria\u00e7\u00e3o de perfis de solicita\u00e7\u00e3o<\/a>.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">No Couchbase 7.0, a cria\u00e7\u00e3o de perfil foi inclu\u00edda para subconsultas, incluindo a cria\u00e7\u00e3o de perfil de subconsultas de <em>UDFs em linha<\/em>.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">No entanto, com os novos recursos do Couchbase 7.6, a cria\u00e7\u00e3o de perfil foi estendida para instru\u00e7\u00f5es SQL++ dentro de <em>UDFs de JavaScript<\/em>.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Nas vers\u00f5es anteriores, para criar perfis de instru\u00e7\u00f5es em um UDF JavaScript, o usu\u00e1rio precisava abrir a defini\u00e7\u00e3o da fun\u00e7\u00e3o, executar individualmente cada instru\u00e7\u00e3o no UDF e coletar seus perfis. Essa etapa adicional n\u00e3o ser\u00e1 mais necess\u00e1ria na vers\u00e3o 7.6.0!<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Agora, quando a cria\u00e7\u00e3o de perfil estiver ativada, se a instru\u00e7\u00e3o contiver a execu\u00e7\u00e3o do UDF JavaScript, os perfis de todas as instru\u00e7\u00f5es SQL++ executadas no UDF tamb\u00e9m ser\u00e3o coletados. E essas informa\u00e7\u00f5es de cria\u00e7\u00e3o de perfil relacionadas ao UDF estar\u00e3o dispon\u00edveis na sa\u00edda da solicita\u00e7\u00e3o, <em>system:active_requests<\/em> e <em>system:completed_requests<\/em> espa\u00e7os de chaves do sistema tamb\u00e9m.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Exemplo 1:<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Criar um UDF JavaScript <em>js1<\/em> em uma biblioteca global <em>lib1<\/em>\u00a0por meio do ponto de extremidade REST ou da interface do usu\u00e1rio.<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\">fun\u00e7\u00e3o js1() {\r\n\r\n    var query = SELECT * FROM default:`travel-sample`.inventory.airline LIMIT 1;\r\n\r\n    var res = [];\r\n    for (const row of query) {\r\n        res.push(row);\r\n   }\r\n    query.close()\r\n\r\n    return res;\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Crie a fun\u00e7\u00e3o SQL++ correspondente:<\/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;\"> Execute o UDF com a cria\u00e7\u00e3o de perfil ativada:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">EXECUTE FUNCTION js1();\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">No <\/span><b>perfil<\/b><span style=\"font-weight: 400;\"> da resposta retornada, a se\u00e7\u00e3o <\/span><b>executionTimings<\/b><span style=\"font-weight: 400;\"> A subse\u00e7\u00e3o cont\u00e9m um campo <\/span><b>~udfStatements<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><b>~udfStatements<\/b><span style=\"font-weight: 400;\">\u00a0\u00e9 uma matriz de informa\u00e7\u00f5es de cria\u00e7\u00e3o de perfil que cont\u00e9m uma entrada para cada instru\u00e7\u00e3o SQL++ dentro do UDF JavaScript.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Cada entrada no <\/span><b>~udfStatements<\/b><span style=\"font-weight: 400;\"> A se\u00e7\u00e3o cont\u00e9m:<\/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;\">A \u00e1rvore de execu\u00e7\u00e3o da declara\u00e7\u00e3o. Ela cont\u00e9m informa\u00e7\u00f5es de m\u00e9tricas e tempos de cada etapa da execu\u00e7\u00e3o da instru\u00e7\u00e3o.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>declara\u00e7\u00e3o<\/b> &#8211; <span style=\"font-weight: 400;\">A string de declara\u00e7\u00e3o.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>fun\u00e7\u00e3o<\/b> &#8211; <span style=\"font-weight: 400;\">O nome da fun\u00e7\u00e3o em que a instru\u00e7\u00e3o foi executada. Isso \u00e9 \u00fatil para identificar o UDF que executou o comando quando h\u00e1 execu\u00e7\u00f5es de UDFs aninhadas.<\/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\": nulo,\r\n  \"results\": [\r\n    [\r\n      {\r\n        \"airline\": {\r\n          \"indicativo\": \"MILE-AIR\",\r\n          \"country\" (pa\u00eds): \"United States\" (Estados Unidos),\r\n          \"iata\": \"Q5\",\r\n          \"icao\": \"MLA\",\r\n          \"id\": 10,\r\n          \"name\": \"40-Mile Air\",\r\n          \"type\" (tipo): \"airline\"\r\n        }\r\n      }\r\n    ]\r\n  ],\r\n  \"status\": \"success\" (sucesso),\r\n  \"metrics\" (m\u00e9tricas): {\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\" (perfil): {\r\n    \"phaseTimes\": {\r\n      \"authorize\": \"12.835\u00b5s\",\r\n      \"fetch\": \"374.667\u00b5s\",\r\n      \"instantiate\" (instanciar): \"27.75\u00b5s\",\r\n      \"parse\" (analisar): \"251.708\u00b5s\",\r\n      \"plan\" (planejar): \"9.125\u00b5s\",\r\n      \"primaryScan\": \"813.249\u00b5s\",\r\n      \"primaryScan.GSI\": \"813.249\u00b5s\",\r\n      \"project\" (projeto): \"5.541\u00b5s\",\r\n      \"run\" (execu\u00e7\u00e3o): \"27.925833ms\",\r\n      \"stream\" (fluxo): \"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\" (fluxo): 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\" (Autorizar),\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\" (privil\u00e9gios): {\r\n        \"List\": []\r\n      },\r\n      \"~child\": {\r\n        \"#operator\": \"Sequence\" (Sequ\u00eancia),\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\" (tipo): \"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\" (Autorizar),\r\n            \"#stats\": {\r\n              \"#phaseSwitches\": 4,\r\n              \"execTime\": \"2.626\u00b5s\",\r\n              \"servTime\": \"7.166\u00b5s\"\r\n            },\r\n            \"privileges\" (privil\u00e9gios): {\r\n              \"List\": [\r\n                {\r\n                  \"Priv\": 7,\r\n                  \"Props\": 0,\r\n                  \"Target\" (destino): \"default:travel-sample.inventory.airline\"\r\n                }\r\n              ]\r\n            },\r\n            \"~child\": {\r\n              \"#operator\": \"Sequence\" (Sequ\u00eancia),\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\" (\u00edndice): \"def_inventory_airline_primary\",\r\n                  \"index_projection\": {\r\n                    \"primary_key\": true\r\n                  },\r\n                  \"keyspace\": \"airline\",\r\n                  \"limit\" (limite): \"1\",\r\n                  \"namespace\": \"default\",\r\n                  \"optimizer_estimates\": {\r\n                    \"cardinality\": 187,\r\n                    \"cost\" (custo): 45.28617059639748,\r\n                    \"fr_cost\": 12.1780009122802,\r\n                    \"size\" (tamanho): 12\r\n                  },\r\n                  \"scope\" (escopo): \"invent\u00e1rio\",\r\n                  \"using\": \"gsi\"\r\n                },\r\n                {\r\n                  \"#operator\": \"Fetch\" (buscar),\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\" (custo): 192.01699202888378,\r\n                    \"fr_cost\": 24.89848658838975,\r\n                    \"size\" (tamanho): 204\r\n                  },\r\n                  \"scope\" (escopo): \"inventory\" (invent\u00e1rio)\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\" (custo): 194.6878862611588,\r\n                    \"fr_cost\": 24.912769445246838,\r\n                    \"size\" (tamanho): 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\" (Limite),\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\" (custo): 24.927052302103924,\r\n                    \"fr_cost\": 24.927052302103924,\r\n                    \"size\" (tamanho): 204\r\n                  }\r\n                },\r\n                {\r\n                  \"#operator\": \"Receive\" (Receber),\r\n                  \"#stats\": {\r\n                    \"#phaseSwitches\": 3,\r\n                    \"execTime\": \"10.324833ms\",\r\n                    \"kernTime\": \"792ns\",\r\n                    \"state\" (estado): \"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      \"~vers\u00f5es\": [\r\n        \"7.6.0-N1QL\",\r\n        \"7.6.0-1847-enterprise\"\r\n      ]\r\n    }\r\n  }\r\n}<\/pre>\n<h2>Planos de consulta com EXPLAIN FUNCTION<\/h2>\n<p><span style=\"font-weight: 400;\">O SQL++ oferece outro recurso maravilhoso para acessar o plano de uma instru\u00e7\u00e3o com a instru\u00e7\u00e3o EXPLAIN. Por\u00e9m, o comando EXPLAIN n\u00e3o se estende a planos de comandos dentro de UDFs - nem UDFs Inline nem JavaScript.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Nas vers\u00f5es anteriores, para analisar os planos de consulta do SQL++ em uma UDF, era necess\u00e1rio que o usu\u00e1rio abrisse a defini\u00e7\u00e3o da fun\u00e7\u00e3o e executasse individualmente um EXPLAIN em todas as instru\u00e7\u00f5es da UDF.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Essas etapas extras s\u00e3o minimizadas no Couchbase 7.6 com a introdu\u00e7\u00e3o de uma nova declara\u00e7\u00e3o-<em>EXPLICAR A FUN\u00c7\u00c3O<\/em>. Essa instru\u00e7\u00e3o faz exatamente o que o EXPLAIN faz, mas para instru\u00e7\u00f5es SQL++ em um UDF.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Vamos explorar como usar a instru\u00e7\u00e3o EXPLAIN FUNCTION!<\/span><\/p>\n<h3>Sintaxe<\/h3>\n<pre class=\"lang:default decode:true\">explain_function ::= 'EXPLAIN' 'FUNCTION' function<\/pre>\n<p><span style=\"font-weight: 400;\">Aqui, <em>fun\u00e7\u00e3o<\/em>\u00a0refere-se ao nome da fun\u00e7\u00e3o.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Para obter informa\u00e7\u00f5es mais detalhadas sobre a sintaxe, consulte a documenta\u00e7\u00e3o.<\/span><\/p>\n<h3>Pr\u00e9-requisitos<\/h3>\n<p><span style=\"font-weight: 400;\">Para executar o EXPLAIN FUNCTION em um UDF, o usu\u00e1rio deve ter <a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/userfun.html#rbac-privileges\">Permiss\u00f5es RBAC<\/a> para <\/span><i><span style=\"font-weight: 400;\">executar<\/span><\/i><span style=\"font-weight: 400;\"> a fun\u00e7\u00e3o.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">O usu\u00e1rio tamb\u00e9m deve ter as permiss\u00f5es RBAC necess\u00e1rias para executar as instru\u00e7\u00f5es SQL++ no corpo da fun\u00e7\u00e3o UDF.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Aqui est\u00e3o os <a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/security\/roles.html\">fun\u00e7\u00f5es compat\u00edveis com o Couchbase<\/a>.<\/span><\/p>\n<h3>UDF em linha<\/h3>\n<p><span style=\"font-weight: 400;\">EXPLAIN FUNCTION em uma UDF em linha retornar\u00e1 os planos de consulta de todas as subconsultas dentro de sua defini\u00e7\u00e3o.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Exemplo 2 - EXPLAIN FUNCTION em uma fun\u00e7\u00e3o inline<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Crie uma UDF em linha e execute EXPLAIN FUNCTION nela:<\/span><\/p>\n<pre class=\"lang:default decode:true\">CREATE FUNCTION inline1() { (\r\n  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;\">Os resultados da declara\u00e7\u00e3o acima conter\u00e3o:<\/span><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\"><b>fun\u00e7\u00e3o<\/b><span style=\"font-weight: 400;\">\u00a0- O nome da fun\u00e7\u00e3o em que EXPLAIN FUNCTION foi executado.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>planos<\/b><span style=\"font-weight: 400;\">\u00a0- Uma matriz de informa\u00e7\u00f5es do plano que cont\u00e9m uma entrada para cada subconsulta dentro do UDF Inline.<\/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\" (custo): 25.117642854609013,\r\n                \"plan\" (plano): {\r\n                    \"#operator\": \"Sequence\" (Sequ\u00eancia),\r\n                    \"~children\": [\r\n                        {\r\n                            \"#operator\": \"IndexScan3\",\r\n                            \"bucket\": \"travel-sample\",\r\n                            \"index\" (\u00edndice): \"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\" (custo): 12.200561852726496,\r\n                                \"fr_cost\": 12.179450078755286,\r\n                                \"size\" (tamanho): 12\r\n                            },\r\n                            \"scope\" (escopo): \"invent\u00e1rio\",\r\n                            \"spans\": [\r\n                                {\r\n                                    \"exato\": verdadeiro,\r\n                                    \"range\" (intervalo): [\r\n                                        {\r\n                                            \"high\": \"\\\\\"Zachar Bay\\\\\"\",\r\n                                            \"inclusion\" (inclus\u00e3o): 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\" (buscar),\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\" (custo): 25.082370508382763,\r\n                                \"fr_cost\": 24.96843677065826,\r\n                                \"size\" (tamanho): 249\r\n                            },\r\n                            \"scope\" (escopo): \"inventory\" (invent\u00e1rio)\r\n                        },\r\n                        {\r\n                            \"#operator\": \"Paralelo\",\r\n                            \"~child\": {\r\n                                \"#operator\": \"Sequence\" (Sequ\u00eancia),\r\n                                \"~children\": [\r\n                                    {\r\n                                        \"#operator\": \"Filtro\",\r\n                                        \"condition\": \"((`airport`.`city`) = \\\\\"Zachar Bay\\\\\")\",\r\n                                        \"optimizer_estimates\": {\r\n                                            \"cardinality\": 1.1176470588235294,\r\n                                            \"cost\" (custo): 25.100006681495888,\r\n                                            \"fr_cost\": 24.98421650449632,\r\n                                            \"size\" (tamanho): 249\r\n                                        }\r\n                                    },\r\n                                    {\r\n                                        \"#operator\": \"InitialProject\" (Projeto inicial),\r\n                                        \"discard_original\": true,\r\n                                        \"optimizer_estimates\": {\r\n                                            \"cardinality\": 1.1176470588235294,\r\n                                            \"cost\" (custo): 25.117642854609013,\r\n                                            \"fr_cost\": 24.99999623833438,\r\n                                            \"size\" (tamanho): 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;\">As instru\u00e7\u00f5es SQL++ dentro dos UDFs JavaScript podem ser de dois tipos e o EXPLAIN FUNCTION funciona de forma diferente com base na maneira como a instru\u00e7\u00e3o SQL++ \u00e9 chamada.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Aqui est\u00e1 a refer\u00eancia da documenta\u00e7\u00e3o para <a href=\"https:\/\/docs.couchbase.com\/server\/current\/javascript-udfs\/calling-n1ql-from-javascript.html\">Chamada de SQL++ em fun\u00e7\u00f5es JavaScript<\/a>.<\/span><\/p>\n<h4>SQL++ incorporado<\/h4>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">O SQL++ incorporado \u00e9 \"incorporado\" no corpo da fun\u00e7\u00e3o e sua detec\u00e7\u00e3o \u00e9 tratada pelo transpilador JavaScript.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">A EXPLAIN FUNCTION pode retornar planos de consulta para instru\u00e7\u00f5es SQL++ incorporadas.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4><\/h4>\n<h4>\u00a0SQL++ executado pela chamada da fun\u00e7\u00e3o N1QL()<\/h4>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">O SQL++ tamb\u00e9m pode ser executado passando uma instru\u00e7\u00e3o na forma de uma cadeia de caracteres como argumento para a fun\u00e7\u00e3o N1QL().<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Ao analisar a fun\u00e7\u00e3o para poss\u00edveis instru\u00e7\u00f5es SQL++ para executar o EXPLAIN, \u00e9 dif\u00edcil obter a string din\u00e2mica no argumento da fun\u00e7\u00e3o. Isso s\u00f3 pode ser resolvido de forma confi\u00e1vel em tempo de execu\u00e7\u00e3o.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Com esse racioc\u00ednio, o EXPLAIN FUNCTION n\u00e3o retorna os planos de consulta para instru\u00e7\u00f5es SQL++ executadas por meio de chamadas N1QL(). Em vez disso, retorna os n\u00fameros de linha em que as chamadas de fun\u00e7\u00e3o N1QL() foram feitas. Esse n\u00famero de linha \u00e9 calculado a partir do in\u00edcio da defini\u00e7\u00e3o da fun\u00e7\u00e3o.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">O usu\u00e1rio pode ent\u00e3o mapear os n\u00fameros de linha na defini\u00e7\u00e3o real da fun\u00e7\u00e3o e investigar mais a fundo.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3><span style=\"font-weight: 400;\">Exemplo 3 - EXPLAIN FUNCTION em uma fun\u00e7\u00e3o JavaScript externa<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Criar um UDF JavaScript <em>js2<\/em> em uma biblioteca global <em>lib1<\/em> por meio do ponto de extremidade REST ou da interface do usu\u00e1rio:<\/span><\/p>\n<pre class=\"lang:js decode:true\">fun\u00e7\u00e3o js2() {\r\n    \/\/ SQL++ executado por uma chamada de fun\u00e7\u00e3o N1QL()\r\n    var query1 = N1QL(\"UPDATE default:`travel-sample` SET test = 1 LIMIT 1\");\r\n    \r\n    \/\/ SQL++ incorporado\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;\"> Crie a fun\u00e7\u00e3o SQL++ correspondente:<\/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;\"> Execute EXPLAIN FUNCTION na fun\u00e7\u00e3o SQL++:<\/span><\/p>\n<pre class=\"lang:default decode:true\">EXPLAIN FUNCTION js2;<\/pre>\n<p><span style=\"font-weight: 400;\">Os resultados da declara\u00e7\u00e3o acima conter\u00e3o:<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li style=\"font-weight: 400;\"><b>fun\u00e7\u00e3o<\/b><span style=\"font-weight: 400;\">\u00a0- O nome da fun\u00e7\u00e3o em que EXPLAIN FUNCTION foi executado.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>n\u00fameros_linha<\/b><span style=\"font-weight: 400;\">\u00a0- Uma matriz de n\u00fameros de linha calculada a partir do in\u00edcio da defini\u00e7\u00e3o da fun\u00e7\u00e3o JavaScript em que h\u00e1 chamadas de fun\u00e7\u00e3o N1QL().<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>planos<\/b><span style=\"font-weight: 400;\">\u00a0- Uma matriz de informa\u00e7\u00f5es do plano que cont\u00e9m uma entrada para cada <\/span><i><span style=\"font-weight: 400;\">incorporado<\/span><\/i><span style=\"font-weight: 400;\"> instru\u00e7\u00e3o SQL++ dentro do 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\" (custo): 25.51560885530435,\r\n      \"plan\" (plano): {\r\n        \"#operator\": \"Authorize\" (Autorizar),\r\n        \"privileges\": {\r\n          \"List\": [\r\n            {\r\n              \"Alvo\": \"default:travel-sample\",\r\n              \"Priv\": 7,\r\n              \"Props\": 0\r\n            }\r\n          ]\r\n        },\r\n        \"~child\": {\r\n          \"#operator\": \"Sequence\" (Sequ\u00eancia),\r\n          \"~children\": [\r\n            {\r\n              \"#operator\": \"Sequence\" (Sequ\u00eancia),\r\n              \"~children\": [\r\n                {\r\n                  \"#operator\": \"Sequence\" (Sequ\u00eancia),\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\" (limite): \"1\",\r\n                      \"namespace\": \"default\",\r\n                      \"optimizer_estimates\": {\r\n                        \"cardinality\": 31591,\r\n                        \"cost\" (custo): 5402.279801258844,\r\n                        \"fr_cost\": 12.170627071041082,\r\n                        \"size\" (tamanho): 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\" (custo): 46269.39474997121,\r\n                        \"fr_cost\": 25.46387878667884,\r\n                        \"size\" (tamanho): 669\r\n                      }\r\n                    },\r\n                    {\r\n                      \"#operator\": \"Paralelo\",\r\n                      \"~child\": {\r\n                        \"#operator\": \"Sequence\" (Sequ\u00eancia),\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\" (custo): 47086.49704894546,\r\n                              \"fr_cost\": 25.489743820991595,\r\n                              \"size\" (tamanho): 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\" (Limite),\r\n                  \"expr\": \"1\",\r\n                  \"optimizer_estimates\": {\r\n                    \"cardinality\" (cardinalidade): 1,\r\n                    \"cost\" (custo): 25.51560885530435,\r\n                    \"fr_cost\": 25.51560885530435,\r\n                    \"size\" (tamanho): 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\" (custo): 25.51560885530435,\r\n                \"fr_cost\": 25.51560885530435,\r\n                \"size\" (tamanho): 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>Restri\u00e7\u00f5es<\/h3>\n<p><span style=\"font-weight: 400;\">Se a fun\u00e7\u00e3o N1QL() tiver sido usada como alias em uma defini\u00e7\u00e3o de fun\u00e7\u00e3o JavaScript, o EXPLAIN FUNCTION n\u00e3o poder\u00e1 retornar os n\u00fameros de linha em que essa fun\u00e7\u00e3o com alias foi chamada. Por exemplo:<\/span><\/p>\n<pre class=\"lang:js decode:true\">fun\u00e7\u00e3o js3() {\r\n  var alias = N1QL;\r\n  var q = alias(\"SELECT 1\");\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Se o UDF contiver execu\u00e7\u00f5es de UDFs aninhados, o EXPLAIN FUNCTION n\u00e3o suportar\u00e1 a gera\u00e7\u00e3o de planos de consulta de instru\u00e7\u00f5es SQL++ dentro desses UDFs aninhados.<\/span><\/p>\n<h2>Resumo<\/h2>\n<p>O Couchbase 7.6 apresenta novos recursos para a depura\u00e7\u00e3o de UDFs, que ajudar\u00e3o os usu\u00e1rios a examinar facilmente a execu\u00e7\u00e3o de UDFs.<\/p>\n<p>Consulte os links da documenta\u00e7\u00e3o a seguir para saber mais ou confira as outras inova\u00e7\u00f5es do Couchbase 7.6:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/couchbase-server-7-6-top-developer-features\/\">Recursos do Couchbase Server 7.6 que os desenvolvedores v\u00e3o adorar<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/userfun.html\">Fun\u00e7\u00f5es definidas pelo usu\u00e1rio<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/createfunction.html#create-function-inline\"> UDFs em linha<\/a><\/li>\n<li><span style=\"font-weight: 400;\"><a href=\"https:\/\/docs.couchbase.com\/server\/current\/javascript-udfs\/javascript-functions-with-couchbase.html\">Um guia para UDFs JavaScript<\/a><\/span><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/createfunction.html#create-function-external\">Cria\u00e7\u00e3o de um UDF externo<\/a><\/li>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/from-n1ql-to-javascript-and-back-part-1-introduction\/\">S\u00e9rie de blogs sobre UDFs de JavaScript<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/explain.html\">Declara\u00e7\u00e3o EXPLAIN do Couchbase SQL++<\/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 v25.9 (Yoast SEO v25.9) - 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\/pt\/improved-debuggability-for-sql-user-defined-functions\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\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\/pt\/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\":\"pt-BR\",\"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\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\":\"pt-BR\",\"@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\/pt\/author\/dhanyagowrish\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Depura\u00e7\u00e3o de UDFs do SQL++ aprimorada no Couchbase 7.6","description":"O Couchbase 7.6 apresenta novos recursos para depurar fun\u00e7\u00f5es definidas pelo usu\u00e1rio (UDFs), o que ajudar\u00e1 os usu\u00e1rios a examinar a execu\u00e7\u00e3o com facilidade. Saiba mais sobre eles aqui.","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\/pt\/improved-debuggability-for-sql-user-defined-functions\/","og_locale":"pt_BR","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\/pt\/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":"pt-BR","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":"Depura\u00e7\u00e3o de UDFs do SQL++ aprimorada no 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":"O Couchbase 7.6 apresenta novos recursos para depurar fun\u00e7\u00f5es definidas pelo usu\u00e1rio (UDFs), o que ajudar\u00e1 os usu\u00e1rios a examinar a execu\u00e7\u00e3o com facilidade. Saiba mais sobre eles aqui.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/improved-debuggability-for-sql-user-defined-functions\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@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":"Blog do Couchbase","description":"Couchbase, o banco de dados 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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@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, engenheiro de software","image":{"@type":"ImageObject","inLanguage":"pt-BR","@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\/pt\/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\/pt\/wp-json\/wp\/v2\/posts\/15566","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/85183"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=15566"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/15566\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/15569"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=15566"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=15566"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=15566"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=15566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}