Example #1
0
void tmDecode(short type, void * src, std::tm * dst)
{
    switch (type & ~1)
    {
    case SQL_TIMESTAMP:
        isc_decode_timestamp(static_cast<ISC_TIMESTAMP*>(src), dst);
        break;
    case SQL_TYPE_TIME:
        isc_decode_sql_time(static_cast<ISC_TIME*>(src), dst);
        break;
    case SQL_TYPE_DATE:
        isc_decode_sql_date(static_cast<ISC_DATE*>(src), dst);
        break;
    default:
        std::ostringstream msg;
        msg << "Unexpected type of date/time field (" << type << ")";
        throw soci_error(msg.str());
    }
}
Example #2
0
static void call_php(char *name, PARAMDSC *r, int argc, PARAMDSC **argv)
{
	do {
		zval callback, args[4], *argp[4], return_value;
		PARAMVARY *res = (PARAMVARY*)r->dsc_address;
		int i;

		INIT_ZVAL(callback);
		ZVAL_STRING(&callback,name,0);

		LOCK();
		
		/* check if the requested function exists */
		if (!zend_is_callable(&callback, 0, NULL TSRMLS_CC)) {
			break;
		}
		
		UNLOCK();
	
		/* create the argument array */
		for (i = 0; i < argc; ++i) {

			INIT_ZVAL(args[i]);
			argp[i] = &args[i];
			
			/* test arg for null */
			if (argv[i]->dsc_flags & DSC_null) {
				ZVAL_NULL(argp[i]);
				continue;
			}

			switch (argv[i]->dsc_dtype) {
				ISC_INT64 l;
				struct tm t;
				char const *fmt;
				char d[64];

				case dtype_cstring:
					ZVAL_STRING(argp[i], (char*)argv[i]->dsc_address,0);
					break;

				case dtype_text:
					ZVAL_STRINGL(argp[i], (char*)argv[i]->dsc_address, argv[i]->dsc_length,0);
					break;

				case dtype_varying:
					ZVAL_STRINGL(argp[i], ((PARAMVARY*)argv[i]->dsc_address)->vary_string,
						((PARAMVARY*)argv[i]->dsc_address)->vary_length,0);
					break;

				case dtype_short:
					if (argv[i]->dsc_scale == 0) {
						ZVAL_LONG(argp[i], *(short*)argv[i]->dsc_address);
					} else {
						ZVAL_DOUBLE(argp[i],
							((double)*(short*)argv[i]->dsc_address)/scales[-argv[i]->dsc_scale]);
					}
					break;

				case dtype_long:
					if (argv[i]->dsc_scale == 0) {
						ZVAL_LONG(argp[i], *(ISC_LONG*)argv[i]->dsc_address);
					} else {
						ZVAL_DOUBLE(argp[i],
							((double)*(ISC_LONG*)argv[i]->dsc_address)/scales[-argv[i]->dsc_scale]);
					}
					break;

				case dtype_int64:
					l = *(ISC_INT64*)argv[i]->dsc_address;

					if (argv[i]->dsc_scale == 0 && l <= LONG_MAX && l >= LONG_MIN) {
						ZVAL_LONG(argp[i], (long)l);
					} else {
						ZVAL_DOUBLE(argp[i], ((double)l)/scales[-argv[i]->dsc_scale]);
					}
					break;

				case dtype_real:
					ZVAL_DOUBLE(argp[i], *(float*)argv[i]->dsc_address);
					break;

				case dtype_double:
					ZVAL_DOUBLE(argp[i], *(double*)argv[i]->dsc_address);
					break;

				case dtype_sql_date:
					isc_decode_sql_date((ISC_DATE*)argv[i]->dsc_address, &t);
					ZVAL_STRINGL(argp[i], d, strftime(d, sizeof(d), INI_STR("ibase.dateformat"), &t),1); 
					break;

				case dtype_sql_time:
					isc_decode_sql_time((ISC_TIME*)argv[i]->dsc_address, &t);
					ZVAL_STRINGL(argp[i], d, strftime(d, sizeof(d), INI_STR("ibase.timeformat"), &t),1); 
					break;

				case dtype_timestamp:
					isc_decode_timestamp((ISC_TIMESTAMP*)argv[i]->dsc_address, &t);
					ZVAL_STRINGL(argp[i], d, strftime(d, sizeof(d), INI_STR("ibase.timestampformat"), &t),1); 
					break;
			}
		}

		LOCK();

		/* now call the function */
		if (FAILURE == call_user_function(EG(function_table), NULL,
				&callback, &return_value, argc, argp TSRMLS_CC)) {
			UNLOCK();
			break;
		}
		
		UNLOCK();

		for (i = 0; i < argc; ++i) {
			switch (argv[i]->dsc_dtype) {
				case dtype_sql_date:
				case dtype_sql_time:
				case dtype_timestamp:
					zval_dtor(argp[i]);
					
			}
		}

		/* return whatever type we got back from the callback: let DB handle conversion */
		switch (Z_TYPE(return_value)) {

			case IS_LONG:
				r->dsc_dtype = dtype_long;
				*(long*)r->dsc_address = Z_LVAL(return_value);
				r->dsc_length = sizeof(long);
				break;

			case IS_DOUBLE:
				r->dsc_dtype = dtype_double;
				*(double*)r->dsc_address = Z_DVAL(return_value);
				r->dsc_length = sizeof(double);
				break;

			case IS_NULL:
				r->dsc_flags |= DSC_null;
				break;

			default:
				convert_to_string(&return_value);

			case IS_STRING:
				r->dsc_dtype = dtype_varying;
				memcpy(res->vary_string, Z_STRVAL(return_value),
					(res->vary_length = min(r->dsc_length-2,Z_STRLEN(return_value))));
				r->dsc_length = res->vary_length+2;
				break;
		}
				
		zval_dtor(&return_value);

		return;

	} while (0);
	
	/**
	* If we end up here, we should report an error back to the DB engine, but
	* that's not possible. We can however report it back to PHP.
	*/
	LOCK();
	php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error calling function '%s' from database", name);
	UNLOCK();
}
Example #3
0
//function fb_store_row based on fiebird's apifull example
void fb_store_row(rlm_sql_firebird_conn_t *conn)
{
	int dtype;
	struct tm times;
	ISC_QUAD bid;
	int i;
	XSQLVAR *var;
	VARY * vary;

	/* assumed: id, username, attribute, value, op */
	if (conn->row_fcount<conn->sqlda_out->sqld)  {
		i = conn->row_fcount;
		conn->row_fcount = conn->sqlda_out->sqld;
		conn->row = (char **) realloc(conn->row, conn->row_fcount * sizeof(char *));
		conn->row_sizes = (int *) realloc(conn->row_sizes, conn->row_fcount * sizeof(int));

		while( i <conn->row_fcount) {
			conn->row[i] = 0;
			conn->row_sizes[i++] = 0;
		}
	}

	for (i = 0, var = conn->sqlda_out->sqlvar; i < conn->sqlda_out->sqld; var++, i++) {
		/*
		 *	Initial buffer size to store field's data is 256 bytes
		 */
		if (conn->row_sizes[i]<256) {
			conn->row[i] = (char *) realloc(conn->row[i], 256);
			conn->row_sizes[i] = 256;
		}

		if (IS_NULL(var)) {
			strcpy(conn->row[i], "NULL");
			continue;
		}

		dtype = var->sqltype & ~1;

		switch (dtype) {
		case SQL_TEXT:
			if (conn->row_sizes[i]<= var->sqllen) {
				conn->row_sizes[i] = var->sqllen + 1;
				conn->row[i] = realloc(conn->row[i],
						       conn->row_sizes[i]);
			}

			memmove(conn->row[i], var->sqldata, var->sqllen);
			conn->row[i][var->sqllen] = 0;

			break;
		case SQL_VARYING:
			vary = (VARY*) var->sqldata;
			if (conn->row_sizes[i] <= vary->vary_length) {
				conn->row_sizes[i] = vary->vary_length + 1;
				conn->row[i] = realloc(conn->row[i],
						       conn->row_sizes[i]);
		   	}
			memmove(conn->row[i], vary->vary_string, vary->vary_length);
			conn->row[i][vary->vary_length] = 0;

			break;

		case SQL_FLOAT:
			snprintf(conn->row[i], conn->row_sizes[i], "%15g",
				 *(float ISC_FAR *) (var->sqldata));
			break;
		case SQL_SHORT:
		case SQL_LONG:
		case SQL_INT64:
			{
				ISC_INT64 value = 0;
				short field_width = 0;
				short dscale = 0;
				char *p;
				p = conn->row[i];

				switch (dtype) {
				case SQL_SHORT:
					value = (ISC_INT64) *(short *)var->sqldata;
					field_width = 6;
					break;
				case SQL_LONG:
					value = (ISC_INT64) *(int *)var->sqldata;
					field_width = 11;
					break;
				case SQL_INT64:
					value = (ISC_INT64) *(ISC_INT64 *)var->sqldata;
					field_width = 21;
					break;
				}
				dscale = var->sqlscale;

				if (dscale < 0) {
					ISC_INT64 tens;
					short j;

					tens = 1;
					for (j = 0; j > dscale; j--) {
						tens *= 10;
					}

					if (value >= 0) {
						sprintf(p, "%*lld.%0*lld",
							field_width - 1 + dscale,
							(ISC_INT64) value / tens,
							-dscale,
							(ISC_INT64) value % tens);
					} else if ((value / tens) != 0) {
						sprintf (p, "%*lld.%0*lld",
							field_width - 1 + dscale,
							(ISC_INT64) (value / tens),
							-dscale,
							(ISC_INT64) -(value % tens));
					} else {
						sprintf(p, "%*s.%0*lld", field_width - 1 + dscale,
							"-0", -dscale, (ISC_INT64) - (value % tens));
					}
				} else if (dscale) {
					sprintf(p, "%*lld%0*d", field_width,
						(ISC_INT64) value, dscale, 0);
				} else {
					sprintf(p, "%*lld", field_width,
						(ISC_INT64) value);
				}
			}
			break;

		case SQL_D_FLOAT:
		case SQL_DOUBLE:
			snprintf(conn->row[i], conn->row_sizes[i], "%24f",
				 *(double ISC_FAR *) (var->sqldata));
			break;

		case SQL_TIMESTAMP:
			isc_decode_timestamp((ISC_TIMESTAMP ISC_FAR *)var->sqldata, &times);
			snprintf(conn->row[i], conn->row_sizes[i], "%04d-%02d-%02d %02d:%02d:%02d.%04d",
				 times.tm_year + 1900,
				 times.tm_mon + 1,
				 times.tm_mday,
				 times.tm_hour,
				 times.tm_min,
				 times.tm_sec,
				 ((ISC_TIMESTAMP *)var->sqldata)->timestamp_time % 10000);
			break;

		case SQL_TYPE_DATE:
			isc_decode_sql_date((ISC_DATE ISC_FAR *)var->sqldata, &times);
			snprintf(conn->row[i], conn->row_sizes[i], "%04d-%02d-%02d",
				 times.tm_year + 1900,
				 times.tm_mon + 1,
				 times.tm_mday);
			break;

		case SQL_TYPE_TIME:
			isc_decode_sql_time((ISC_TIME ISC_FAR *)var->sqldata, &times);
			snprintf(conn->row[i], conn->row_sizes[i], "%02d:%02d:%02d.%04d",
				 times.tm_hour,
				 times.tm_min,
				 times.tm_sec,
				 (*((ISC_TIME *)var->sqldata)) % 10000);
			break;

		case SQL_BLOB:
		case SQL_ARRAY:
			/* Print the blob id on blobs or arrays */
			bid = *(ISC_QUAD ISC_FAR *) var->sqldata;
			snprintf(conn->row[i], conn->row_sizes[i], "%08" ISC_LONG_FMT "x:%08" ISC_LONG_FMT "x",
				 bid.gds_quad_high, bid.gds_quad_low);
			break;

		}
	}
}
Example #4
0
/*
** Pushes the indexed value onto the lua stack
*/
static void push_column(lua_State *L, int i, cur_data *cur) {
    int varcharlen;
    struct tm timevar;
    char timestr[256];
    ISC_STATUS blob_stat;
    isc_blob_handle blob_handle = NULL;
    ISC_QUAD blob_id;
    luaL_Buffer b;
    char *buffer;
    unsigned short actual_seg_len;

    if( (cur->out_sqlda->sqlvar[i].sqlind != NULL) &&
            (*(cur->out_sqlda->sqlvar[i].sqlind) != 0) ) {
        /* a null field? */
        lua_pushnil(L);
    } else {
        switch(cur->out_sqlda->sqlvar[i].sqltype & ~1) {
        case SQL_VARYING:
            varcharlen = (int)isc_vax_integer(cur->out_sqlda->sqlvar[i].sqldata, 2);
            lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata+2, varcharlen);
            break;
        case SQL_TEXT:
            lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata, cur->out_sqlda->sqlvar[i].sqllen);
            break;
        case SQL_SHORT:
            lua_pushnumber(L, *(short*)(cur->out_sqlda->sqlvar[i].sqldata));
            break;
        case SQL_LONG:
            lua_pushnumber(L, *(long*)(cur->out_sqlda->sqlvar[i].sqldata));
            break;
        case SQL_INT64:
            lua_pushnumber(L, (lua_Number)*(ISC_INT64*)(cur->out_sqlda->sqlvar[i].sqldata));
            break;
        case SQL_FLOAT:
            lua_pushnumber(L, *(float*)(cur->out_sqlda->sqlvar[i].sqldata));
            break;
        case SQL_DOUBLE:
            lua_pushnumber(L, *(double*)(cur->out_sqlda->sqlvar[i].sqldata));
            break;
        case SQL_TYPE_TIME:
            isc_decode_sql_time((ISC_TIME*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
            strftime(timestr, 255, "%X", &timevar);
            lua_pushstring(L, timestr);
            break;
        case SQL_TYPE_DATE:
            isc_decode_sql_date((ISC_DATE*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
            strftime(timestr, 255, "%x", &timevar);
            lua_pushstring(L, timestr);
            break;
        case SQL_TIMESTAMP:
            isc_decode_timestamp((ISC_TIMESTAMP*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
            strftime(timestr, 255, "%x %X", &timevar);
            lua_pushstring(L, timestr);
            break;
        case SQL_BLOB:
            /* get the BLOB ID and open it */
            memcpy(&blob_id, cur->out_sqlda->sqlvar[i].sqldata, sizeof(ISC_QUAD));
            isc_open_blob2(	cur->env->status_vector,
                            &cur->conn->db, &cur->conn->transaction,
                            &blob_handle, &blob_id, 0, NULL );
            /* fetch the blob data */
            luaL_buffinit(L, &b);
            buffer = luaL_prepbuffer(&b);

            blob_stat = isc_get_segment(	cur->env->status_vector,
                                            &blob_handle, &actual_seg_len,
                                            LUAL_BUFFERSIZE, buffer );
            while(blob_stat == 0 || cur->env->status_vector[1] == isc_segment) {
                luaL_addsize(&b, actual_seg_len);
                buffer = luaL_prepbuffer(&b);
                blob_stat = isc_get_segment(	cur->env->status_vector,
                                                &blob_handle, &actual_seg_len,
                                                LUAL_BUFFERSIZE, buffer );
            }

            /* finnished, close the BLOB */
            isc_close_blob(cur->env->status_vector, &blob_handle);
            blob_handle = NULL;

            luaL_pushresult(&b);
            break;
        default:
            lua_pushstring(L, "<unsupported data type>");
            break;
        }
    }
}
Example #5
0
char * getdata( int pos )
{
   short dtype;
   char  data[ MAX_BUFFER ], * p;
   char  blob_s[ 20 ], date_s[ 25 ];
   short len;
   long  status[ 20 ];

   struct tm times;
   ISC_QUAD  bid;
   XSQLVAR * var;

   if( ( pos + 1 ) > sqlda->sqln )
      return "error";

   var = sqlda->sqlvar;

   var += pos;

   dtype = var->sqltype & ~1;
   p     = data;

   if( ( var->sqltype & 1 ) && ( *var->sqlind < 0 ) )
   {
      switch( dtype )
      {
         case SQL_TEXT:
         case SQL_VARYING:
            len = var->sqllen;
            break;
         case SQL_SHORT:
            len = 6;
            if( var->sqlscale > 0 )
               len += var->sqlscale;
            break;
         case SQL_LONG:
            len = 11;
            if( var->sqlscale > 0 )
               len += var->sqlscale;
            break;
         case SQL_INT64:
            len = 21;
            if( var->sqlscale > 0 )
               len += var->sqlscale;
            break;
         case SQL_FLOAT:
            len = 15;
            break;
         case SQL_DOUBLE:
            len = 24;
            break;
         case SQL_TIMESTAMP:
            len = 24;
            break;
         case SQL_TYPE_DATE:
            len = 10;
            break;
         case SQL_TYPE_TIME:
            len = 13;
            break;
         case SQL_BLOB:
         case SQL_ARRAY:
         default:
            len = 17;
            break;
      }
      if( ( dtype == SQL_TEXT ) || ( dtype == SQL_VARYING ) )
         sprintf( p, "%-*s ", len, "NULL" );
      else
         sprintf( p, "%*s ", len, "NULL" );
   }
   else
   {
      switch( dtype )
      {
         case SQL_TEXT:
            sprintf( p, "%.*s ", var->sqllen, var->sqldata );
            break;

         case SQL_VARYING:
            sprintf( p, "%.*s ", var->sqllen, var->sqldata );
            break;

         case SQL_SHORT:
         case SQL_LONG:
         case SQL_INT64:
         {
            ISC_INT64 value       = 0;
            short     field_width = 0;
            short     dscale;

            switch( dtype )
            {
               case SQL_SHORT:
                  value       = ( ISC_INT64 ) *( short ISC_FAR * ) var->sqldata;
                  field_width = 6;
                  break;
               case SQL_LONG:
                  value       = ( ISC_INT64 ) *( long ISC_FAR * ) var->sqldata;
                  field_width = 11;
                  break;
               case SQL_INT64:
                  value       = ( ISC_INT64 ) *( ISC_INT64 ISC_FAR * ) var->sqldata;
                  field_width = 21;
                  break;
            }
            dscale = var->sqlscale;
            if( dscale < 0 )
            {
               ISC_INT64 tens;
               short     i;

               tens = 1;
               for( i = 0; i > dscale; i-- )
               {
                  tens *= 10;

                  if( value >= 0 )
                  {

                     sprintf( p,
                              "%*" ISC_INT64_FORMAT "d.%0*"
                              ISC_INT64_FORMAT "d",
                              field_width - 1 + dscale,
                              ( ISC_INT64 ) ( value / tens ), -dscale,
                              ( ISC_INT64 ) ( value % tens ) );
                  }
                  else if( ( value / tens ) != 0 )
                  {

                     sprintf( p,
                              "%*" ISC_INT64_FORMAT "d.%0*"
                              ISC_INT64_FORMAT "d",
                              field_width - 1 + dscale,
                              ( ISC_INT64 ) ( value / tens ), -dscale,
                              ( ISC_INT64 ) -( value % tens ) );
                  }
                  else
                  {

                     sprintf( p, "%*s.%0*" ISC_INT64_FORMAT "d",
                              field_width - 1 + dscale,
                              "-0", -dscale,
                              ( ISC_INT64 ) -( value % tens ) );
                  }
               }
            }
            else if( dscale )
            {
               sprintf( p, "%*" ISC_INT64_FORMAT "d%0*d",
                        field_width, ( ISC_INT64 ) value, dscale, 0 );
            }
            else
            {
               sprintf( p, "%*" ISC_INT64_FORMAT "d",
                        field_width, ( ISC_INT64 ) value );
            }
         };
            break;

         case SQL_FLOAT:
            sprintf( p, "%15g ", *( float ISC_FAR * ) ( var->sqldata ) );
            break;

         case SQL_DOUBLE:
            sprintf( p, "%24f ", *( double ISC_FAR * ) ( var->sqldata ) );
            break;

         case SQL_TIMESTAMP:
            isc_decode_timestamp( ( ISC_TIMESTAMP ISC_FAR * ) var->sqldata, &times );
            sprintf( date_s, "%04d-%02d-%02d %02d:%02d:%02d.%04lui",
                     times.tm_year + 1900,
                     times.tm_mon + 1,
                     times.tm_mday,
                     times.tm_hour,
                     times.tm_min,
                     times.tm_sec,
                     ( ( ISC_TIMESTAMP * ) var->sqldata )->timestamp_time % 10000 );
            sprintf( p, "%*s ", 24, date_s );
            break;

         case SQL_TYPE_DATE:
            isc_decode_sql_date( ( ISC_DATE ISC_FAR * ) var->sqldata, &times );
            sprintf( date_s, "%04d-%02d-%02d",
                     times.tm_year + 1900, times.tm_mon + 1, times.tm_mday );
            sprintf( p, "%*s ", 10, date_s );
            break;

         case SQL_TYPE_TIME:
            isc_decode_sql_time( ( ISC_TIME ISC_FAR * ) var->sqldata, &times );
            sprintf( date_s, "%02d:%02d:%02d.%04lui",
                     times.tm_hour,
                     times.tm_min,
                     times.tm_sec, ( *( ( ISC_TIME * ) var->sqldata ) ) % 10000 );
            sprintf( p, "%*s ", 13, date_s );
            break;

         case SQL_BLOB:
         case SQL_ARRAY:
            /* Print the blob id on blobs or arrays */
            bid = *( ISC_QUAD ISC_FAR * ) var->sqldata;
            sprintf( blob_s, "%08x:%08x", ( unsigned int ) bid.gds_quad_high,
                     ( unsigned int ) bid.gds_quad_low );
            sprintf( p, "%17s ", blob_s );
            break;

         default:
            break;
      }
   }

   return p;
}
Example #6
0
int _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowidx) 
{
	unsigned int curfield = 0;
	XSQLVAR var;
	long fetch_stat = 0, blob_stat = 0;
	ISC_QUAD bid;
	isc_blob_handle blob_handle = NULL; /* Blob handle. */ 
	char blob_segment[80];
	unsigned short actual_seg_len;		
	struct tm times;
	char date_s[25];
	unsigned int sizeattrib;
	dbi_data_t *data = NULL;
	ibase_stmt_t *istmt = (ibase_stmt_t *)result->result_handle;
	ibase_conn_t *iconn = (ibase_conn_t *)result->conn->connection;

	fetch_stat = isc_dsql_fetch(iconn->status_vector, &(istmt->stmt), SQL_DIALECT_V6, istmt->osqlda);

	if (fetch_stat != 0) {
		result->numrows_matched--;
		return 0;
	}

	while (curfield < result->numfields) {
		var = istmt->osqlda->sqlvar[curfield];
		data = &row->field_values[curfield];

		/**
		 * If the column holds a NULL value mark it as NULL 
		 */
		if ( (var.sqltype & 1) && ( *var.sqlind < 0)) {
			_set_field_flag( row, curfield, DBI_VALUE_NULL, 1);
			curfield++;
			continue;
		}
		
		switch ( result->field_types[curfield] ) {
		case DBI_TYPE_STRING: 
			if(result->field_attribs[curfield] & DBI_STRING_FIXEDSIZE) {
				data->d_string = strdup(var.sqldata);
				row->field_sizes[curfield] = (unsigned long long) var.sqllen;
			} else {
				vary_t *vary = NULL;
				vary = (vary_t *) var.sqldata;
				data->d_string = malloc(vary->vary_length+1);
				memcpy(data->d_string, vary->vary_string, vary->vary_length);
				data->d_string[vary->vary_length] = '\0';
				row->field_sizes[curfield] = (unsigned long long) vary->vary_length;
			}
			break;
			
		case DBI_TYPE_INTEGER:
			sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_INTEGER_SIZE1, DBI_INTEGER_SIZE8);
			switch (sizeattrib) {
			case DBI_INTEGER_SIZE1:
				
			case DBI_INTEGER_SIZE2:
				data->d_short = *(short *) var.sqldata; break;
			case DBI_INTEGER_SIZE3:
			case DBI_INTEGER_SIZE4:
				data->d_long = *(int *) var.sqldata; break;
			case DBI_INTEGER_SIZE8:
				data->d_longlong = *(ISC_INT64 *) var.sqldata; break;
			default:
				break;
			}
			break;
		case DBI_TYPE_DECIMAL:
			sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_DECIMAL_SIZE4, DBI_DECIMAL_SIZE8);
			switch (sizeattrib) {
			case DBI_DECIMAL_SIZE4:
				data->d_float = *(float *) (var.sqldata); break;
			case DBI_DECIMAL_SIZE8:
				data->d_double = *(double *) (var.sqldata); break;
			default:
				break;
			}
			break;
		case DBI_TYPE_DATETIME:
			sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_DATETIME_DATE, DBI_DATETIME_TIME);
			
			if (sizeattrib&DBI_DATETIME_TIME
			    && sizeattrib&DBI_DATETIME_DATE) {
 				isc_decode_timestamp((ISC_TIMESTAMP *)var.sqldata, &times);
				sprintf(date_s, "%04d-%02d-%02d %02d:%02d:%02d",
					times.tm_year + 1900,
					times.tm_mon+1,
					times.tm_mday,
					times.tm_hour,
					times.tm_min,
					times.tm_sec);
			}
			else if (sizeattrib&DBI_DATETIME_TIME) {
				isc_decode_sql_time((ISC_TIME *)var.sqldata, &times);
				sprintf(date_s, "%02d:%02d:%02d",
					times.tm_hour,
					times.tm_min,
					times.tm_sec);
			}
			else {
				isc_decode_sql_date((ISC_DATE *)var.sqldata, &times);
				sprintf(date_s, "%04d-%02d-%02d",
					times.tm_year + 1900,
					times.tm_mon+1,
					times.tm_mday);
			}
			data->d_datetime = _dbd_parse_datetime(date_s, sizeattrib);		
			break;
		
		case DBI_TYPE_BINARY:
			bid = *(ISC_QUAD *) var.sqldata;
			
			isc_open_blob2( iconn->status_vector, &(iconn->db), &(iconn->trans), &blob_handle, &bid, 0, NULL );
			blob_stat = isc_get_segment( iconn->status_vector, &blob_handle,  &actual_seg_len,  
						     sizeof(blob_segment), blob_segment  );

			data->d_string = malloc(sizeof(actual_seg_len));
			memcpy(data->d_string, blob_segment, actual_seg_len);
			row->field_sizes[curfield] = actual_seg_len;

			while (blob_stat == 0 || iconn->status_vector[1] == isc_segment) { 
				blob_stat = isc_get_segment(iconn->status_vector, &blob_handle, 
							    &actual_seg_len, 
							    sizeof(blob_segment), blob_segment); 

				data->d_string = realloc(data->d_string, 
							 row->field_sizes[curfield] + 
							 actual_seg_len);
				memcpy(data->d_string+row->field_sizes[curfield], 
				       blob_segment, actual_seg_len);
				row->field_sizes[curfield] += actual_seg_len;
			} 
			isc_close_blob(iconn->status_vector, &blob_handle);
			row->field_sizes[curfield] = _dbd_decode_binary(data->d_string, data->d_string);
			break;
				
		default:
			break;
		}
		
		
		curfield++;
	}

	if( fetch_stat != 100L ) {
		result->rows = realloc(result->rows, (sizeof(dbi_row_t *) * (result->numrows_matched+1)));
		result->numrows_matched++;
	}

	return result->numrows_matched;
}