Table operator UDF - VARCHAR length

Extensibility

Table operator UDF - VARCHAR length

Hi experts

I am  developing a table operator UDF using C/C++ . Teradata release is 15.0.0.8 .

As a part of PoC of table operator functionality, a C UDF is created which uses table operator interface functions . This UDF takes two tables as input, performs a basic calculation and displays the output stream. Everything works fine when the datatype of all the fields in the table are of type INTEGER.

When the datatype of the input table is VARCHAR, the program fails.

Can you please check the below and mention where is the mistake?

/*********declaration of input and output stream************/

   FNC_TblOpColumnDef_t *Input_columns; // input stream column definitions

   FNC_TblOpColumnDef_t *Output_columns; // output stream column definitions

   FNC_TblOpHandle_t *Input_handle;    //input stream

   FNC_TblOpHandle_t *Output_handle;  //output stream

                          .

                          .

                          .

                          .

loop (for i = 0 to number_of_outputcolumns-1)

{

Output_columns->column_types[i].datatype = INTEGER_DT;

Output_columns->column_types[i].bytesize = SIZEOF_INTEGER;


}

                          .

                          .

               allocated memory for input columns/output columns

               initialized the input column/output column

                          .

                          .

               opened the input stream/ output stream

                          .

                          .

                          .

   loop (while  == TBLOP_SUCCESS)

   {

        loop (for i = 0 to number_of_outputcolumns-1)

            {

               FNC_TblOpGetAttributeByNdx(Input_handle, i, (void **) &ptr, &null_ind, &length);    //Get the value pointed by Input_Handle and return the attribute value to pointer location ptr

              FNC_TblOpBindAttributeByNdx(Output_handle, i , (int *)ptr, 0 , sizeof(int));  //bind the value at the location ptr to Output handle

             }

   FNC_TblOpWrite(Output_handle);

   }

The above code works fine when the table contains only integer

******DDL of input table*******

CREATE MULTISET TABLE tab_test ,NO FALLBACK ,

     NO BEFORE JOURNAL,

     NO AFTER JOURNAL,

     CHECKSUM = DEFAULT,

     DEFAULT MERGEBLOCKRATIO

     (

      A INTEGER,

      B INTEGER,

      C INTEGER)

PRIMARY INDEX ( A );

when the code is modified to use VARCHAR fields below error is coming

 " Executed as Single statement.  Failed [7815 : HY000] Invalid length for variable length attribute at index 0. 

Elapsed time = 00:00:02.057 "

Modifications done in the program for VARCHAR

                          .

                          .

                          .

                          .

loop (for i = 0 to number_of_outputcolumns-1)

{

 Output_columns->column_types[i].datatype = VARCHAR_DT; 

 Output_columns->column_types[i].bytesize = SIZEOF_VARCHAR_UNICODE(10); 

 Output_columns->column_types[i].charset =  UNICODE_CT; 



}

                          .

                          .


                          .

                          .

 loop (while  == TBLOP_SUCCESS)

   {

        loop (for i = 0 to number_of_outputcolumns-1)

            {

               FNC_TblOpGetAttributeByNdx(Input_handle, i, (void **) &ptr, &null_ind, &length);    

              FNC_TblOpBindAttributeByNdx(Output_handle, i , (char *)ptr, 0 , 10 * sizeof(VARCHAR_UNICODE)); 

 // tried giving the variable "length" instead of  "10 * sizeof(VARCHAR_UNICODE)", tried numericals  etc NOT working

             }

   FNC_TblOpWrite(Output_handle);

   }

******DDL of input table*******

CREATE SET TABLE tab_test ,NO FALLBACK ,

     NO BEFORE JOURNAL,

     NO AFTER JOURNAL,

     CHECKSUM = DEFAULT,

     DEFAULT MERGEBLOCKRATIO

     (

      A VARCHAR(10) CHARACTER SET UNICODE NOT CASESPECIFIC NOT NULL)

UNIQUE PRIMARY INDEX UPI_GL_Account_Code ( A );


1 REPLY
Teradata Employee

Re: Table operator UDF - VARCHAR length

This is an old question but thought I'd share an answer in case others happen upon it this thread with the same question.  Instead of using the bytesize variable which is for fixed length types try using the size.length field instead...So change this:

Output_columns->column_types[i].bytesize = SIZEOF_VARCHAR_UNICODE(10);

To this:

Output_columns->column_types[i].size.length = SIZEOF_VARCHAR_UNICODE(10); 

The second part of this where you are calling FNC_TblOpBindAttributeByNdx.  You need to make sure that what you are passing has a specific form.  It must be pointing to your varchar data that has a 2 byte short value at the beginning which is the length of the character data.  Also the last parameter in this function needs to be the length of the data in the pointer PLUS those 2 bytes.  Here is an example I've used albeit with a LATIN character set that you can modify for UNICODE...

char strval[30];

*((unsigned short*)strval) = strlen("string to output");

strcpy(strval + 2, "string to output");

FNC_TblOpBindAttributeByNdx(ctx->OutHandle, 1, strval, NOTNULL, strlen("string to output")+2);

Hope this helps.