Stored Function Framework

Two kinds of C stored functions can be introduced into the MIM server: regular C stored functions and built-in C stored functions.

Regular Stored Functions

Regular C stored functions are introduced as follows. Each stored function needs to be built into a separate shared library (e.g., a .so or .dll file) named with the name of the function it contains. For example, slice.so will contain the slice C stored function. The .so file then goes into the directory <libraryDir>/attr/plugin, which is the directory that the MIM server will check for stored functions to load upon startup.

The utility functions available for the stored functions to use are in the include/xmim_cfunc_api.h file. Utility functions mostly operate on internal MIM objects hidden from the stored function implementation. Their implementation is found in the files cfunc/xmim_cfunc_api.c and plugin/xmim_cfunc_api_model.c. The second file contains the functions which are used by the model classes of the framework and is included into the first one. This file (cfunc/xmim_cfunc_api.c) is linked into the client, while plugin/xmim_cfunc\api.c is linked into the server.

The current list of helper functions is provided below.

  //create new xmim_cfunc_args struct  xmim_cfunc_args *xmim_cfunc_new_cfunc_args ();

  //set the error string of args to message
  void xmim_cfunc_set_error (xmim_cfunc_args *args, char *message);

  //free error string
  void xmim_cfunc_free_error (xmim_cfunc_args *args);

  //creates a xmim_cfunc_date_time struct initialized to the values provided
  xmim_cfunc_date_time *xmim_cfunc_get_date_time 
                           (xmim_cfunc_args *args,
                            unsigned year, unsigned month, unsigned day, 
                            unsigned hour, unsigned minute, 
                            unsigned second);

  //creates a xmim_cfunc_date_time struct initialized to the values provided
  xmim_cfunc_date_time *xmim_cfunc_get_full_date_time 
                           (xmim_cfunc_args *args,
                            unsigned year, unsigned month, 
                            unsigned day, unsigned_week_day, 
                            unsigned day_of_month, unsigned hour,                                        
                            unsigned minute, unsigned second);
  //creates a xmim_cfunc_date_time struct initialized to

  //the values provided, values include milliseconds
  xmim_cfunc_date_time *xmim_cfunc_get_full_date_time_with_millis 
                           (xmim_cfunc_args *args, 
                            unsigned year, unsigned month, 
                            unsigned day, 
                            unsigned week_day, 
                            unsigned day_of_month,
                            unsigned hour, unsigned minute, 
                            unsigned second, 
                            unsigned millisecond);
  //creates a xmim_cfunc_date_time struct initialized to
  //the values provided, values include milliseconds
  xmim_cfunc_date_time *xmim_cfunc_get_date_time_with_millis 
                           (xmim_cfunc_args *args, 
                            unsigned year, unsigned month, 
                            unsigned day, 
                            unsigned hour, unsigned minute, 
                            unsigned second, unsigned millisecond);

  void xmim_cfunc_set_date (xmim_cfunc_args *args, 
                            xmim_cfunc_date_time *dt,
                            unsigned year, unsigned month, unsigned day);

  //sets the fields of dt to the specified values
  void xmim_cfunc_set_full_date_time 
                           (xmim_cfunc_args *args,
                            xmim_cfunc_date_time *dt,
                            unsigned year, unsigned month, unsigned day, 
                            unsigned week_day, unsigned day_of_month,                                 
                            unsigned hour, unsigned minute, unsigned second);

  //sets the fields of dt to the specified values, values include milliseconds
  void xmim_cfunc_set_full_date_time_with_millis 
                           (xmim_cfunc_args *args, 
                            xmim_cfunc_date_time *dt,
                            unsigned year, unsigned month, unsigned day, 
                            unsigned week_day, unsigned day_of_month,
                            unsigned hour, unsigned minute, 
                            unsigned second, unsigned millisecond);

  //returns a MimDateTime object initialized to the values in dt
  void *xmim_cfunc_get_mim_date_time 
                           (xmim_cfunc_args *args,
                            xmim_cfunc_date_time *dt);

  //get the value of ExObject pointed to by ex_object on date time dt
  double xmim_cfunc_get_value 
                          (xmim_cfunc_args *args,
                           void *ex_object, xmim_cfunc_date_time *dt);

  //compares the arguments passed to a cfunc
  //returns 1 if they are equal, 0 otherwise
  int xmim_cfunc_equal (xmim_cfunc_args *arg1, xmim_cfunc_args *arg2);

  //Applies time offset named time_offset_name to date time date
  //and returns a pointer to the new date time struct.
  //Here time_series_name and time_offset_name are the names of
  //the time series and time offset input parameters correspondingly.
  //So, the name of the time series might be args->attr_args->names[0]
  //and the name of the time offset may be args->offset_args->names[0].
  //Delegates the functionality to 
  //xmim_cfunc_date_time *xmim_cfunc_apply_time_offset 
  //                      (xmim_cfunc_args *args,
  //                       xmim_cfunc_date_time *date, 
  //                       void *time_series, 
  //                       void *time_offset)
  xmim_cfunc_date_time *xmim_cfunc_apply_time_offset_to_args 
                          (xmim_cfunc_args *args,
                           xmim_cfunc_date_time *date, 
                           char *time_series_name, 
                           char *time_offset_name);


  //Applies time offset time_offset to date time date
  //and returns a pointer to the new date time struct.
  //Uses an ExObject called time_series to perform the offset.
  //Returns NULL and sets the error message on error.
  xmim_cfunc_date_time *xmim_cfunc_apply_time_offset 
                          (xmim_cfunc_args *args,
                           xmim_cfunc_date_time *date, 
                           void *time_series, 
                           void *time_offset);

  //Applies time period called period_name to the date time dt.
  //Uses ExObject pointed to by an attr arg called time_series_name
  //to apply the period.
  //Returns 1 upon success, 0 on failure (and sets the error message).
  int xmim_cfunc_apply_time_period 
                          (xmim_cfunc_args *args,
                           xmim_cfunc_date_time *dt, char *period_name,
                           char *time_series_name,
                           int include_left, int include_right, 
                           xmim_cfunc_date_time *left_date, 
                           xmim_cfunc_date_time *right_date);

  //Populates the list of relations based on path.
  xmim_cfunc_relation_list* xmim_cfunc_get_relations_by_name 
                          (xmim_cfunc_args *args,
                           char *path);

  //Populates the list of slice-specific relations based on path for slice C Stored Functions.
  xmim_cfunc_date_relation_list*  xmim_cfunc_get_date_relations_by_name 
                          (xmim_cfunc_args *args, 
                           char *path);

  //Returns a pointer to an empty time series.
  void *xmim_cfunc_get_empty_time_series (xmim_cfunc_args *args, void *ex_object);

  //Returns a pointer to the ExRelcol Object based on the given relname and colname.
  void *xmim_cfunc_get_time_series (xmim_cfunc_args *args, char *relname, char *colname);

  //Sets int value for the time series object (TsTimeSeries is assumed) 
  //produced by on date time dt cfunc_get_empty_time_series
  int xmim_cfunc_set_int_value_for_time_series 
                          (xmim_cfunc_args *args, 
                           void *time_series, int value, 
                           xmim_cfunc_date_time *dt);

  //Sets double value for the time series object (TsTimeSeries is assumed) 
  //produced by on date time dt cfunc_get_empty_time_series
  int xmim_cfunc_set_double_value_for_time_series 
                          (xmim_cfunc_args *args,
                           void *time_series, double value,
                           xmim_cfunc_date_time *dt);

  //Gets the value of the time series (TsTimeSeries is assumed) time_series
  //on date time dt.
  double xmim_cfunc_get_value_for_time_series 
                          (xmim_cfunc_args *args,
                           void *time_series, xmim_cfunc_date_time *dt);

  //Sets the args->trading_pattern to the ExTradingPattern 
  //computed by ex_object
  void xmim_cfunc_compute_trading_pattern 
                          (xmim_cfunc_args *args,
                           void *ex_object);

  //Sets the args->trading_date_range to the ExTradingPattern 
  //computed by ex_object
  void xmim_cfunc_compute_trading_date_range 
                          (xmim_cfunc_args *args,
                           void *ex_object);

  //Returns a pointer to the ExDateRange object initialized
  //to from and to.
  void *xmim_cfunc_get_ex_trading_date_range 
                          (xmim_cfunc_args *args,
                           xmim_cfunc_date_time *from, 
                           xmim_cfunc_date_time *to);

  //Returns a pointer to the mATimeOffset object initialized
  //to multiple, unit and direction.
  void *xmim_cfunc_get_time_offset 
                          (xmim_cfunc_args *args,
                           int multiple, xmim_cfunc_dwmqy unit,
                           xmim_cfunc_direction direction);

  //Returns a pointer to the mTimePeriod object initialized
  //to fromOffset and toOffset. Defaults to today for NULL inputs.

  void *xmim_cfunc_get_time_period 
                          (xmim_cfunc_args *args,
                           void *fromOffset, void *toOffset);

  //compare val to NaN
  int xmim_cfunc_isNaN (xmim_cfunc_args *args,
                        double val);

  //make a not a number object out of val
  void xmim_cfunc_makeNan (xmim_cfunc_args *args,
                           double *val);

  xmim_cfunc_date_time *xmim_cfunc_get_from_date 
                          (xmim_cfunc_args *args, 
                           void *ex_object);

  xmim_cfunc_date_time *xmim_cfunc_get_to_date 
                          (xmim_cfunc_args *args, 
                           void *ex_object);

  //sets an argument of type type called name to value
  int xmim_cfunc_set_arg (xmim_cfunc_args *args,
                          xmim_cfunc_arg_type type, void *value, char *name);

  //sets a constant arg called name to k
  int xmim_cfunc_set_int_constant (xmim_cfunc_args *args, int k, char *name);

  //sets a constant arg called name to k
  int xmim_cfunc_set_dbl_constant (xmim_cfunc_args *args, double k, char *name);

  //sets a category arg called name to cat
  int xmim_cfunc_set_category (xmim_cfunc_args *args, char *cat, char *name);
 
  //sets a string arg called name to str
  void xmim_cfunc_set_string (xmim_cfunc_args *args, char *str, char *name);

  //sets an attr arg called name to attr
  int xmim_cfunc_set_attr (xmim_cfunc_args *args, void *attr, char *name);

  //sets a time offset arg called name to offset
  int xmim_cfunc_set_offset (xmim_cfunc_args *args, void *offset, char *name);

  //sets a time period arg called name to period
  int xmim_cfunc_set_period (xmim_cfunc_args *args, void *period, char *name);

  //sets a security arg called name to relation
  int xmim_cfunc_set_security (xmim_cfunc_args *args, void *relation, char *name);

  //sets the xmim_cfunc state called name to state
  int xmim_cfunc_set_state (xmim_cfunc_args *args, void *state, char *name);

  //returns a pointer to an argument of type type called name
  //returns NULL and sets the error message if an argument with 
  //such name is not found
  void *xmim_cfunc_get_arg (xmim_cfunc_args *args, xmim_cfunc_arg_type type, char *name);

  //returns a pointer to a constant called name
  void *xmim_cfunc_get_int_constant (xmim_cfunc_args *args, char *name);

  //returns a pointer to a constant called name
  void *xmim_cfunc_get_dbl_constant (xmim_cfunc_args *args, char *name);

  //returns a pointer to a category called name
  void *xmim_cfunc_get_category (xmim_cfunc_args *args, char *name);

  //returns a pointer to a string called name
  void *xmim_cfunc_get_string (xmim_cfunc_args *args, char *name);

  //returns a pointer to an attr called name
  void *xmim_cfunc_get_attr (xmim_cfunc_args *args, char *name);

  //returns a pointer to a time offset called name
  void *xmim_cfunc_get_offset (xmim_cfunc_args *args, char *name);


  //returns a pointer to a time period called name
  void *xmim_cfunc_get_period (xmim_cfunc_args *args, char *name);

  //returns a pointer to a security called name
  void *xmim_cfunc_get_security (xmim_cfunc_args *args, char *name);

  //returns a pointer to a state called name
  void *xmim_cfunc_get_state (xmim_cfunc_args *args, char *name);

  //frees the args struct
  void xmim_cfunc_free_cfunc_args (xmim_cfunc_args *args);

  //free date time dt
  void xmim_cfunc_free_date_time (xmim_cfunc_args *args, xmim_cfunc_date_time *dt);

  //free MimDateTime object
  void xmim_cfunc_free_mim_date_time (xmim_cfunc_args *args, void *dt);

  //free the time series created by the xmim_cfunc_get_time_series
  //function. Cfuncs MUST use this function to destroy the time
  //series.
  void xmim_cfunc_free_time_series (xmim_cfunc_args *args, void *time_series);

  // free the time series created via cfunc_get_empty_time_series
  // function. ex_object is a pointer to the ExObject instance
  // used as an input parameter in xmim_cfunc_get_empty_time_series
  void xmim_cfunc_free_ts_time_series (xmim_cfunc_args *args, void *time_series);

  //free trading pattern created by cfunc_compute_trading_pattern
  //function
  void xmim_cfunc_free_trading_pattern (xmim_cfunc_args *args;

  //free trading date range created by xmim_cfunc_get_ex_trading_date_range
  //function
  void xmim_cfunc_free_trading_date_range (xmim_cfunc_args *args);

  //free time offset created by xmim_cfunc_get_time_offset
  void xmim_cfunc_free_time_offset (xmim_cfunc_args *args, void *offset);

  //free time period created by xmim_cfunc_get_time_period
  void xmim_cfunc_free_time_period (xmim_cfunc_args *args, void *period);

  //print part of the args
  void xmim_cfunc_print (xmim_cfunc_args *args);

  //print time offset
  void xmim_cfunc_print_time_offset (xmim_cfunc_args *args, void *off);

  //print time period
  void xmim_cfunc_print_time_period (xmim_cfunc_args *args, void *period);

Built-in Stored Functions

Built-in C stored functions are literally “built” into the MIM server, that is the BUILTIN_CSTORED_FUNC_SRCS target of the Makefile needs to be edited to include a particular built-in C stored function source code (to be compiled and later linked into the MIM server).

Built-in C stored functions subclass the model/mBuiltinCStoredFunction class, which itself is abstract. All methods (except get_path) that mBuiltinCStoredFunction subclasses are required to implement are in one-to-one correspondence with the regular plugin functions as is obvious from the names. As with regular C stored functions, compute_trading_pattern and compute_trading_date_range methods are optional. The get_path method is specific to built-in C stored functions and returns the path (within macro's hierarchy) and the name of the given built-in C stored function. For example, the following code in the constructor of CStoredFuncStringExample initializes its path:

this->path = new char[1028];
sprintf (this->path, "%s%s%s", ATTR_MACROS, PATH_SEPARATOR, "builtin_string_example");

Please note that "builtin_string_example" corresponds to the built-in C stored function's name, so the path to this c stored function is "attr/builtin_string_example".

Implementation for the other methods of mBuiltinCStoredFunction subclasses is similar to regular C stored functions. Built-in C stored function sources can be placed anywhere, but it is our suggestion to put them under plugin/ directory. We also suggest to prefix built-in C stored function source file names with cstored_func_ (as in cstored_func_string_example.C) and to prefix the class names with CStoredFunc (as in CStoredFuncStringExample).

There are two examples of built-in C stored functions available. The first one is available under plugin/cstored_func_lazy_predictor.C and mirrors the regular C stored function under apps/plugins/lazy_predictor.c. The second one is under plugin/cstored_func_string_example.C (we will refer to it as string example function). The string example function demonstrates the use of string as input parameters and takes two input string arguments. The input arguments are user-supplied relation name and column name. The function then returns the value corresponding to the given relation and column.

Built-in C stored functions should be "registed" via the register_builtin_cstored_func method of the xmim_server right after the creation of the xmim_server instance in main/api_svr_main.C. The registration of the two example built-in C stored functions is commented out in api_svr_main.C. Just uncomment those lines to query the example built-in C stored functions.