/* * Licensed Materials - Property of HCL * * IBM Informix DataBlade Module * (C) Copyright International Business Machines Corporation 2002. * (c) Copyright HCL Technologies Ltd. 2017. All Rights Reserved. * * COPYRIGHT LICENSE: * This information contains sample application programs in source language, * which illustrate programming techniques on various operating platforms. * You may copy, modify, and distribute these sample programs in any form * without payment to IBM, for the purposes of developing, using, marketing * or distributing application programs conforming to the application * programming interface for the operating platform for which the sample * programs are written. These examples have not been thoroughly tested under * all conditions. IBM, therefore, cannot guarantee or imply reliability, * serviceability, or function of these programs. You may copy, modify, and * distribute these sample programs in any form without payment to IBM for * the purposes of developing, using, marketing, or distributing application * programs conforming to IBM's application programming interfaces. * Each copy or any portion of these sample programs or any derivative work, * must include a copyright notice as follows: * © (your company name) (year). Portions of this code are derived from * IBM Corp. Sample Programs. © Copyright IBM Corp. (enter the year or * years). All rights reserved. * */ /* * SETUP: * create function Interp(TimeSeries) returns TimeSeries * external name 'Interpolate.so(ts_interp)' * language c not variant; * * * USAGE: * select Interp(stock_data) from daily_stocks where stock_id = 901; */ #include #include #include # define TS_MAX_COLS 100 # define DATATYPE "smallfloat" /* * This example interpolates between values to fill in null elements. * It assumes that all columns are of type smallfloat and that there are * less than 100 columns in each element. */ #ifdef NT __declspec(dllexport) #endif ts_timeseries * ts_interp(tsPtr, fParamPtr) ts_timeseries *tsPtr; MI_FPARAM *fParamPtr; { ts_tsdesc *descPtr; ts_tselem tselem; ts_tscan *scan; MI_CONNECTION *conn; ts_typeinfo *typeinfo; int scancode; mi_real *values[TS_MAX_COLS]; mi_real lastValues[TS_MAX_COLS], newValues[TS_MAX_COLS]; mi_boolean nulls[TS_MAX_COLS]; mi_integer minElem, curElem, elem; mi_integer i; mi_boolean noneYet; mi_integer ncols; char strbuf[100]; /* get a connection for libmi */ conn = mi_open(NULL,NULL,NULL); /* open a descriptor for the timeseries */ descPtr = ts_open(conn, tsPtr, mi_fp_rettype(fParamPtr, 0), 0); if ((ncols = (mi_integer) mi_fp_funcstate(fParamPtr)) == 0) { ncols = ts_col_cnt(descPtr); if (ncols > TS_MAX_COLS) { sprintf(strbuf, "Timeseries elements have too many columns, 100 is the max, got %d instead.", ncols); mi_db_error_raise(NULL, MI_FATAL, strbuf, 0); } for (i = 1; i < ncols; i++) { typeinfo = ts_colinfo_number(descPtr, i); if (strlen(typeinfo->ti_typename) != strlen(DATATYPE) || memcmp(typeinfo->ti_typename, DATATYPE, strlen(DATATYPE)) != 0){ sprintf(strbuf, "column was not a %s, got %s instead.", DATATYPE, typeinfo->ti_typename); mi_db_error_raise(NULL, MI_FATAL, strbuf, 0); } } mi_fp_setfuncstate(fParamPtr, (void *) ncols); } noneYet = MI_TRUE; minElem = -1; curElem = 0; /* begin a scan of the whole timeseries */ scan = ts_begin_scan(descPtr, 0, NULL, NULL); while ((scancode = ts_next(scan, &tselem)) != TS_SCAN_EOS) { switch(scancode) { case TS_SCAN_ELEM: /* if this element is not null expand its values */ noneYet = MI_FALSE; ts_get_all_cols(descPtr, tselem, (void **) values, nulls, curElem); if (minElem == -1) { /* save each element */ for (i = 1; i < ncols; i++) lastValues[i] = *values[i]; } else { /* calculate the average */ for (i = 1; i < ncols; i++) { newValues[i] = (*values[i] + lastValues[i])/2.0; lastValues[i] = *values[i]; values[i] = &newValues[i]; } /* update the missing elements */ tselem = ts_make_elem(descPtr, (void **) values, nulls, &elem); for (elem = minElem; elem < curElem; elem++) ts_put_nth_elem(descPtr, tselem, elem); minElem = -1; } break; case TS_SCAN_NULL: if (noneYet) break; /* remember the first null element */ if (minElem == -1) minElem = curElem; break; } curElem++; } ts_end_scan(scan); ts_close(descPtr); return(tsPtr); }