This example shows the C code for the interface function for the parser.
#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); }