This repository has been archived on 2024-01-15. You can view files and clone it, but cannot push or open issues or pull requests.
vn-mysql/udfs/value.cc

100 lines
2.0 KiB
C++

// Value handling functions
#define INT(ptr) (*((long long *) ptr))
#define REAL(ptr) (*((double *) ptr))
#define min(a,b) (a < b ? a : b)
typedef union {
long long i;
double d;
char * s;
} Val;
typedef struct {
Val val;
int is_null;
Item_result type;
unsigned long len;
int free;
} Value;
#define value_ptr(value) (value->is_null ? NULL : (char *) &value->val)
void value_init(Value * value) {
value->is_null = 1;
value->free = 0;
}
void value_free_val(Value *value) {
if (value->free) {
free(value->val.s);
value->free = 0;
}
}
void value_set_null(Value *value) {
value_free_val(value);
value->is_null = 1;
}
void value_set(Value * value, UDF_ARGS *args, int arg_index, int copy) {
char * arg = args->args[arg_index];
if (arg != NULL) {
value->is_null = 0;
value->type = args->arg_type[arg_index];
switch (value->type) {
case INT_RESULT:
value->val.i = INT(arg);
break;
case REAL_RESULT:
value->val.d = REAL(arg);
break;
default:
value->len = args->lengths[arg_index];
if (copy) {
value->free = 1;
value->val.s = (char *) malloc(value->len);
memcpy(value->val.s, arg, value->len);
} else
value->val.s = arg;
}
} else
value->is_null = 1;
}
void value_from_arg(Value * value, UDF_ARGS *args, int arg_index) {
value->free = 0;
value_set(value, args, arg_index, 0);
}
void value_copy_arg(Value * value, UDF_ARGS *args, int arg_index) {
value_free_val(value);
value_set(value, args, arg_index, 1);
}
int value_compare(Value *a, Value *b) {
int cmp;
double real_cmp;
if (!a->is_null && !b->is_null && a->type == b->type) {
switch (a->type) {
case INT_RESULT:
cmp = a->val.i - b->val.i;
break;
case REAL_RESULT:
real_cmp = a->val.d - b->val.d;
cmp = real_cmp == 0.0 ? 0 : (real_cmp > 0.0 ? 1 : -1);
break;
default: // STRING_RESULT & DECIMAL_RESULT
cmp = strncmp(a->val.s, b->val.s, min(a->len, b->len));
if (cmp == 0) cmp = a->len - b->len;
}
} else
cmp = b->is_null && a->is_null ? 0 : (a->is_null ? -1 : 1);
return cmp;
}