17.00 - 17.05 - コントラクト関数に対するC関数定義 - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQL外部ルーチン プログラミング

Product
Advanced SQL Engine
Teradata Database
Release Number
17.00
17.05
Published
2020年6月
Content Type
プログラミング リファレンス
Publication ID
B035-1147-170K-JPN
Language
日本語 (日本)

このサンプルでは、構文解析プログラムのインターフェース関数に対するCコードを示します。

#define  byte unsigned char
#define  boolean int
#define  false 0
#define  true  1
#define  OK    0
#define  SQL_TEXT Latin_Text

#define _CRT_SECURE_NO_DEPRECATE
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqltypes_td.h>

#define FALSE 0
#define TRUE 1

#define MAX_KEY_LEN 100

void  udaggregation_contract (
      INTEGER *result,
      int *indicator_Result,
      char sqlstate[6],
      SQL_TEXT extname[129],
      SQL_TEXT specific_name[129],
      SQL_TEXT error_message[257])
{
   FNC_TblOpColumnDef_t *Output_columns;  // column definition for output stream
   FNC_TblOpColumnDef_t *Input_columns;   // column definition for input stream
   char                 *buf;
   int                  colcount;         // number of columns in output
   int                  i, j, n, k;
   char                 key[MAX_KEY_LEN]; // key in custom clause
   int                  keylen;           // actual key length
   Key_info_t           valuesSUM;        // values associated with key SUM
   Key_info_t           valuesAVG;        // values associated with key AVG
   int                  *index;           // indices of columns in input stream to
                                          // apply aggregates

   boolean_t            found;
   char                 colname[FNC_MAXNAMELEN_EON];

   /* -------- process custom clause information -------- */
   FNC_TblOpGetCustomKeyInfoOf("SUM_AGG", &valuesSUM);
   FNC_TblOpGetCustomKeyInfoOf("AVG_AGG", &valuesAVG);

   // allocate space for values associated with keys "SUM_AGG" and "AVG_AGG"
   valuesSUM.values_r = FNC_malloc( sizeof(Values_t) * valuesSUM.numOfVal );
   valuesAVG.values_r = FNC_malloc( sizeof(Values_t) * valuesAVG.numOfVal );

   // compute number of columns in output stream
   colcount = valuesSUM.numOfVal + valuesAVG.numOfVal;

   // get values associated with key "SUM_AGG"
   FNC_TblOpGetCustomValuesOf(&valuesSUM);

   // get values associated with key "AVG_AGG"
   FNC_TblOpGetCustomValuesOf(&valuesAVG);

   /* ------- define column definition for output stream ------*/

   // Allocate memory for the output columns
   Output_columns = FNC_malloc ( TblOpSIZECOLDEF(colcount) );

   // initialize output columns
   TblOpINITCOLDEF(Output_columns, colcount);

   // Allocate memory for input columns
   Input_columns = FNC_malloc ( TblOpSIZECOLDEF( FNC_TblOpGetColCount(0, 'R') ) );

   // initialize input columns
   TblOpINITCOLDEF( Input_columns, FNC_TblOpGetColCount(0, 'R') );
   FNC_TblOpGetColDef(0, 'R', Input_columns);

   // allocate space for indices of columns in input stream to apply aggregates
   index = FNC_malloc( sizeof(int) * colcount );

   /* ------- Fill in column information for SUM_AGG ------ */

   // Fill in column information for output stream for SUM_AGG
   k = 0;
   found = false;
   for (i = 0; i < valuesSUM.numOfVal; i++)
   {
      // check value corresponds to a column name in input stream
      for (j = 0; j < Input_columns->num_columns; j++)
      {
         if (strncmp(valuesSUM.values_r[i].value,
            Input_columns->column_types[j].column,
            valuesSUM.values_r[i].valueLen) == 0)
         {
               index[k] = j;
               k++;
               found = true;
               break;
         }
      }
      if (! found)
      {
         FNC_TblOpSetError("U0001", "Invalid column name in custom clause.");
         return;
      }
      strcpy(colname, "SUM_");
      strncpy( Output_columns->column_types[i].column,
         strncat(colname, (char *) valuesSUM.values_r[i].value,
        valuesSUM.values_r[i].valueLen),FNC_MAXNAMELEN_EON);
      Output_columns->column_types[i].datatype = REAL_DT;
      Output_columns->column_types[i].bytesize = SIZEOF_FLOAT;
   }

   n = valuesSUM.numOfVal;
   // Fill in column information for output stream for AVG_AGG
   found = false;
   for (i = 0; i < valuesAVG.numOfVal; i++)
   {
      // check value corresponds to a column name in input stream
      for (j = 0; j < Input_columns->num_columns; j++)
      {
         if (strncmp(valuesAVG.values_r[i].value,
            Input_columns->column_types[j].column,
            valuesAVG.values_r[i].valueLen)== 0)
         {
               index[k] = j;
               k++;
               found = true;
               break;
         }
      }
      if (! found)
      {
         FNC_TblOpSetError("U0001", "Invalid column name in custom clause.");
         return;
      }
      strcpy(colname, "AVG_");
      strncpy( Output_columns->column_types[n+i].column,
         strncat(colname, (char *) valuesAVG.values_r[i].value,
            valuesAVG.values_r[i].valueLen), FNC_MAXNAMELEN_EON);
      Output_columns->column_types[n+i].datatype = REAL_DT;
      Output_columns->column_types[n+i].bytesize = SIZEOF_FLOAT;
   }
   // set column definitions for output stream
   FNC_TblOpSetOutputColDef(0, Output_columns);

   // pass indices to table operator in the contract context
   FNC_TblOpSetContractDef(index, sizeof(int) * colcount );

   // release memory
   *result = Output_columns->num_columns;
   FNC_free(Output_columns);
   FNC_free(Input_columns);
   FNC_free(valuesSUM.values_r);
   FNC_free(valuesAVG.values_r);
   FNC_free(index);
}