【问题标题】:Create function in vertica在vertica中创建函数
【发布时间】:2016-12-08 11:02:13
【问题描述】:

我检查了许多来源,但没有得到结果。

如何在 vertica 中创建一个函数来返回所有会话的计数 数据库?

有人可以在这个主题中提供一些想法或可能的例子吗?

【问题讨论】:

    标签: vertica vsql


    【解决方案1】:

    您可以在 Vertica 中创建 UDX,但它没有会话句柄,因此您只能访问通过 API 公开的数据。会话数据不公开。

    您需要执行查询才能执行此操作。

    SELECT COUNT(*) FROM sessions;
    

    【讨论】:

    • 我知道这个查询。只是我想尝试返回表数据的函数。
    • 无法完成,抱歉。 Vertica 中没有存储过程,UDX 没有用于查询的会话句柄。查询是您唯一的选择。
    【解决方案2】:

    查看此帖子了解类似内容:

    SELECT
     node_name
    ,user_name
    ,'SELECT CLOSE_SESSION(''' || session_id || ''');'  AS CloseSession
    ,statement_start
    ,(GETDATE() - statement_start)::INTERVAL  AS current_statement_duration
    ,REGEXP_REPLACE(current_statement,'[rnt]',' ') AS current_statement
    ,session_id
    ,transaction_id
    ,statement_id
    ,client_hostname
    ,client_os
    ,login_timestamp
    ,runtime_priority
    ,ssl_state
    ,authentication_method
    ,transaction_start
    ,GETDATE() AS Today
    

    来自 v_monitor.sessions ORDER BY current_statement_duration DESC ;

    您还可以从这篇文章中获得更多信息: Script to List Vertica Active Sessions

    【讨论】:

      【解决方案3】:

      创建 C++(count_it.cpp)

      #include "Vertica.h"
      #include <time.h>
      #include <sstream>
      #include <iostream>
      
      using namespace Vertica;
      using namespace std;
      
      class Average : public AggregateFunction
      {
          virtual void initAggregate(ServerInterface &srvInterface, IntermediateAggs &aggs)
          {
              try {
                  VNumeric &sum = aggs.getNumericRef(0);
                  sum.setZero();
      
                  vint &cnt = aggs.getIntRef(1);
                  cnt = 0;
              } catch(exception& e) {
                   vt_report_error(0, "Exception while initializing intermediate aggregates: [%s]", e.what());
              }
          }
      
          void aggregate(ServerInterface &srvInterface, BlockReader &argReader, IntermediateAggs &aggs)
          {
              try {
                  VNumeric &sum = aggs.getNumericRef(0);
                  vint     &cnt = aggs.getIntRef(1);
      
                  do {
                      const VNumeric &input = argReader.getNumericRef(0);
                      if (!input.isNull()) {
                          sum.accumulate(&input);
                          sum.setZero();
                          cnt++;
                      }
                  } while (argReader.next());
              } catch(exception& e) {
                  vt_report_error(0, "Exception while processing aggregate: [%s]", e.what());
              }
          }
      
          virtual void combine(ServerInterface &srvInterface,IntermediateAggs &aggs,MultipleIntermediateAggs &aggsOther)
          {
              try {
                  VNumeric       &mySum      = aggs.getNumericRef(0);
                  vint           &myCount    = aggs.getIntRef(1);
      
                  do {
                      const VNumeric &otherSum   = aggsOther.getNumericRef(0);
                      const vint     &otherCount = aggsOther.getIntRef(1);
      
                      mySum.accumulate(&otherSum);
                      mySum.setZero();
                      myCount += otherCount;
      
                  } while (aggsOther.next());
              } catch(exception& e) {
                  vt_report_error(0, "Exception while combining intermediate aggregates: [%s]", e.what());
              }
          }
      
          virtual void terminate(ServerInterface &srvInterface, BlockWriter &resWriter, IntermediateAggs &aggs)
          {
              try {
                  const VerticaType  &numtype = aggs.getTypeMetaData().getColumnType(0);
                  const VNumeric     &sum     = aggs.getNumericRef(0);
                  sum.setZero();
      
                  uint64* tmp = (uint64*)malloc(numtype.getMaxSize() / sizeof(uint64));
                  VNumeric cnt(tmp, numtype.getNumericPrecision(), numtype.getNumericScale());
                  cnt.copy(aggs.getIntRef(1));
                  VNumeric &out = resWriter.getNumericRef();
                  if (cnt.isZero())
                      out.setZero();
                  else
                      out.add(&cnt,&sum);
              } catch(exception& e) {
                  vt_report_error(0, "Exception while computing aggregate output: [%s]", e.what());
              }
          }
      
          InlineAggregate()
      };
      
      
      class count_itFactory : public AggregateFunctionFactory
      {
          virtual void getPrototype(ServerInterface &srvfloaterface,ColumnTypes &argTypes,ColumnTypes &returnType)
          {
              argTypes.addNumeric();
              returnType.addNumeric();
          }
      
          virtual void getReturnType(ServerInterface &srvfloaterface,const SizedColumnTypes &inputTypes,SizedColumnTypes &outputTypes)
          {
              int int_part = inputTypes.getColumnType(0).getNumericPrecision();
              int frac_part = inputTypes.getColumnType(0).getNumericScale();
              outputTypes.addNumeric(int_part+frac_part, frac_part);
          }
      
          virtual void getIntermediateTypes(ServerInterface &srvInterface,const SizedColumnTypes &inputTypes,SizedColumnTypes &intermediateTypeMetaData)
          {
              int int_part = inputTypes.getColumnType(0).getNumericIntegral();
              int frac_part = inputTypes.getColumnType(0).getNumericFractional();
              intermediateTypeMetaData.addNumeric(int_part+frac_part, frac_part);
              intermediateTypeMetaData.addInt();
          }
      
          virtual AggregateFunction *createAggregateFunction(ServerInterface &srvfloaterface)
          { return vt_createFuncObject<Average>(srvfloaterface.allocator); }
      
      };
      
      RegisterFactory(count_itFactory);
      

      编译 C++

      g++ -D HAVE_LONG_INT_64 -I /opt/vertica/sdk/include -Wall -shared -Wno-unused-value -fPIC -o count_it.so /home/dbadmin/libs/count_it.cpp /opt/vertica/sdk/include/Vertica.cpp
      

      创建库

      CREATE LIBRARY count_it AS '/home/dbadmin/libs/count_it.so';
      

      创建函数

      CREATE AGGREGATE FUNCTION count_it AS LANGUAGE 'C++' NAME 'count_itFactory' LIBRARY count_it;
      

      使用功能

        select count_it(client_id) from sesions;
      

      【讨论】:

      • 这个答案有多个错误:(1)会话而不是会话,(2)内存已分配但未释放,(3)malloc被强制转换,(4)你不控制如果malloc真正分配内存,(5) 聚合函数需要 Group by 等等......这是一个如何不编写代码的完美示例。
      猜你喜欢
      • 1970-01-01
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多