Hi All,

Well I think I actually managed to fumble my way to a solution to this.  I
took the example avg_cost UDF function and modified it somewhat (well,
hacked it to pieces).  I've tried this before but I actually tried to
rewrite it, bad mistake.  This time I just deleted all the bits I didn't
need :o)

This seems to work pretty well, I've tested it with queries dealing with
100,000+ records and seems stable.  Of course I don't give any guarantee
that it will work for you, or that it won't blow up your server if you try
it.

Here is the source.  Note that it can only get the last value of integers,
not text, real numbers.

Remember, I don't really know what I'm doing in C, so if there is any bad
coding, don't be nasty :o)

Cheers

Miles

#ifdef STANDARD
#include <stdio.h>
#include <string.h>
#else
#include <global.h>
#include <my_sys.h>
#endif
#include <mysql.h>
#include <m_ctype.h>
#include <m_string.h>           // To get strmov()

#ifdef HAVE_DLOPEN

/* These must be right or mysqld will not find the symbol! */

extern "C" {
my_bool last_init( UDF_INIT* initid, UDF_ARGS* args, char* message );
void last_deinit( UDF_INIT* initid );
void last_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char
*error );
void last_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error
);
double last( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
}

struct last_data
{
  unsigned long long lastvalue;
};


/*
** Average Cost Aggregate Function.
*/
my_bool
last_init( UDF_INIT* initid, UDF_ARGS* args, char* message )
{
  struct last_data*     data;

  if (args->arg_count != 1)
  {
    strcpy(
           message,
           "wrong number of arguments: LAST() requires one arguments"
           );
    return 1;
  }

  if ((args->arg_type[0] != INT_RESULT))
  {
    strcpy(
           message,
           "wrong argument type: LAST() requires an INT"
           );
    return 1;
  }

  initid->maybe_null    = 0;            // The result may be null

  data = new struct last_data;

  initid->ptr = (char*)data;

  return 0;
}

void
last_deinit( UDF_INIT* initid )
{
  delete initid->ptr;
}

void
last_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message )
{
  struct last_data* data = (struct last_data*)initid->ptr;
  data->lastvalue       = 0;

  *is_null = 0;
  last_add( initid, args, is_null, message );
}


void
last_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message )
{

        if (args->args[0] )
        {
        struct last_data* data  = (struct last_data*)initid->ptr;
        data->lastvalue = *((long long*)args->args[0]);
        }
}


double
last( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error )
{
  struct last_data* data = (struct last_data*)initid->ptr;

  return data->lastvalue;
}

#endif /* HAVE_DLOPEN */




---------------------------------------------------------------------
Before posting, please check:
   http://www.mysql.com/manual.php   (the manual)
   http://lists.mysql.com/           (the list archive)

To request this thread, e-mail <[EMAIL PROTECTED]>
To unsubscribe, e-mail <[EMAIL PROTECTED]>
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php

Reply via email to