00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "postgres.h"
00029
00030 #include <float.h>
00031 #include <math.h>
00032
00033 #include "access/gist.h"
00034 #include "access/skey.h"
00035 #include "utils/builtins.h"
00036 #include "lib/stringinfo.h"
00037 #include "utils/array.h"
00038
00039 #include "tsdata.h"
00040
00041
00042
00043
00044
00045
00046 PG_MODULE_MAGIC;
00047
00048
00049
00050
00051
00052 #define ARRPTR(x) ( (double *) ARR_DATA_PTR(x) )
00053 #define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
00054
00055 extern int ts_yyparse();
00056 extern void ts_yyerror(const char *message);
00057 extern int ts_scanner_init(const char *str);
00058 extern void ts_scanner_finish(void);
00059
00063 void i_ts_sax(TS *ts, int32 sax_len,SAX *result);
00064 unsigned char to_base_sax(double val);
00065
00066 bool isNull ( TS_ELEMENT *point );
00067
00068 PG_FUNCTION_INFO_V1(ts_in);
00069 PG_FUNCTION_INFO_V1(ts_out);
00070 PG_FUNCTION_INFO_V1(ts_length);
00071 PG_FUNCTION_INFO_V1(ts_duration);
00072 PG_FUNCTION_INFO_V1(ts_range);
00073 PG_FUNCTION_INFO_V1(ts_sax);
00074 PG_FUNCTION_INFO_V1(ts_mean);
00075 PG_FUNCTION_INFO_V1(ts_std);
00076 PG_FUNCTION_INFO_V1(ts_add);
00077 PG_FUNCTION_INFO_V1(ts_multiply);
00078 PG_FUNCTION_INFO_V1(ts_subtract);
00079 PG_FUNCTION_INFO_V1(ts_divide);
00080 PG_FUNCTION_INFO_V1(ts_subset);
00081
00082 Datum ts_in(PG_FUNCTION_ARGS);
00083 Datum ts_out(PG_FUNCTION_ARGS);
00084 Datum ts_length(PG_FUNCTION_ARGS);
00085 Datum ts_duration(PG_FUNCTION_ARGS);
00086 Datum ts_range(PG_FUNCTION_ARGS);
00087 Datum ts_sax(PG_FUNCTION_ARGS);
00088 Datum ts_mean(PG_FUNCTION_ARGS);
00089 Datum ts_std(PG_FUNCTION_ARGS);
00090 Datum ts_add(PG_FUNCTION_ARGS);
00091 Datum ts_subtract(PG_FUNCTION_ARGS);
00092 Datum ts_multiply(PG_FUNCTION_ARGS);
00093 Datum ts_divide(PG_FUNCTION_ARGS);
00094
00095
00096
00097
00098
00099
00100
00101
00102
00107 Datum
00108 ts_in(PG_FUNCTION_ARGS)
00109 {
00110 char *str = PG_GETARG_CSTRING(0);
00111 TS *result;
00112 int length;
00113 int size;
00114
00115
00116 length = ts_scanner_init(str);
00117 size = SIZE_OF_TS(length);
00118 result = palloc0(size);
00119 SET_VARSIZE(result, size);
00120 result->length = length;
00121
00122 if (ts_yyparse((void *)result) != 0)
00123 ts_yyerror("bogus input");
00124
00125 ts_scanner_finish();
00126
00127 PG_RETURN_TS(result);
00128 }
00129
00133 Datum
00134 ts_out(PG_FUNCTION_ARGS)
00135 {
00136 TS *ts = PG_GETARG_TS(0);
00137 StringInfoData buf;
00138 int i;
00139 int ndig;
00140
00141 if (ts == NULL)
00142 PG_RETURN_TS(NULL);
00143
00144 initStringInfo(&buf);
00145
00146 if ( ts->length > 0 ) {
00147
00148
00149
00150 ndig = DBL_DIG + extra_float_digits;
00151 if (ndig < 1)
00152 ndig = 1;
00153
00154 if (ndig > 5)
00155 ndig = 5;
00156
00157 for ( i = 0; i < ts->length; i++ ) {
00158 if ( i > 0 )
00159 appendStringInfo(&buf, "; ");
00160
00161 if ( !isNull(&(ts->data[i])) ) {
00162 if ( ts->data[i].lower > -HUGE_VAL )
00163 appendStringInfo(&buf, "%.*g", ndig, ts->data[i].lower);
00164
00165 if ( ts->data[i].lower != ts->data[i].upper ) {
00166 appendStringInfoChar(&buf, ':');
00167
00168 if ( ts->data[i].upper < HUGE_VAL )
00169 appendStringInfo(&buf, "%.*g", ndig, ts->data[i].upper);
00170 }
00171 }
00172 else {
00173 appendStringInfo(&buf, "NULL");
00174 }
00175 }
00176
00177 if ( ts->duration > 0 ) {
00178 appendStringInfoChar(&buf, '/');
00179 appendStringInfo(&buf, "%.*g", ndig, ts->duration);
00180 }
00181 }
00182 PG_FREE_IF_COPY(ts, 0);
00183 PG_RETURN_CSTRING(buf.data);
00184 }
00185
00190 Datum
00191 ts_duration(PG_FUNCTION_ARGS)
00192 {
00193 TS *ts = PG_GETARG_TS(0);
00194 float4 duration = ts->duration;
00195
00196 PG_FREE_IF_COPY(ts, 0);
00197 PG_RETURN_FLOAT4(duration);
00198 }
00199
00203 Datum
00204 ts_length(PG_FUNCTION_ARGS)
00205 {
00206 TS *ts = PG_GETARG_TS(0);
00207 int length = ts->length;
00208
00209 PG_FREE_IF_COPY(ts, 0);
00210 PG_RETURN_INT32(length);
00211 }
00212
00213
00218 Datum
00219 ts_range(PG_FUNCTION_ARGS)
00220 {
00221 TS *ts = PG_GETARG_TS(0);
00222 TS *result;
00223 int size, i;
00224 float min = HUGE;
00225 float max = -HUGE;
00226
00227 size = SIZE_OF_TS(1);
00228 result = (TS *) palloc0(size);
00229 SET_VARSIZE(result, size);
00230 result->length = 1;
00231
00232 for (i = 0; i < ts->length; i++) {
00233 if (ts->data[i].lower < min )
00234 min = ts->data[i].lower;
00235 if (ts->data[i].upper > max )
00236 max = ts->data[i].upper;
00237 }
00238
00239 result->data[0].lower = min;
00240 result->data[0].upper = max;
00241
00242 PG_FREE_IF_COPY(ts, 0);
00243 PG_RETURN_TS(result);
00244 }
00245
00249 bool isNull ( TS_ELEMENT *point ) {
00250 return(point->lower > point->upper);
00251 }
00252
00258 Datum ts_sax(PG_FUNCTION_ARGS){
00259 SAX *result;
00260 int size, i;
00261
00262 TS *ts = PG_GETARG_TS(0);
00263
00264 uint32 sax_len = PG_GETARG_UINT32(1);
00265 uint16 card = PG_GETARG_UINT16(2);
00266
00267
00268 size = SIZE_OF_SAX(sax_len);
00269 result = (SAX *) palloc0(size);
00270 SET_VARSIZE(result, size);
00271 i_ts_sax(ts,sax_len,result);
00272 if(card<DEFAULT_CARDINALITY){
00273
00274 for(i=0;i<sax_len;i++){
00275 result->data[i].lower=downgradeLetter(result->data[i].lower,DEFAULT_CARDINALITY,card);
00276 result->data[i].upper=downgradeLetter(result->data[i].upper,DEFAULT_CARDINALITY,card);
00277 result->data[i].cardinality=card;
00278 }
00279 }
00280 PG_FREE_IF_COPY(ts, 0);
00281 PG_RETURN_SAX(result);
00282
00283 }
00284
00285 float i_ts_mean(TS *ts){
00286 float norm, sum;
00287 int i;
00288 int length = ts->length;
00289
00290 sum = 0.0;
00291 norm=(float)length;
00292 for (i = 0; i < length; i++) {
00293 sum += ts->data[i].lower;
00294 sum += ts->data[i].upper;
00295 }
00296
00297
00298 return (sum / (2.0*norm));
00299 }
00300
00301 float i_ts_std(TS *ts){
00302 float norm, sum,sum2,avg;
00303 int i;
00304 int length = ts->length;
00305 sum = 0.0;
00306 norm=(float)length;
00307 for (i = 0; i < length; i++) {
00308 sum += ts->data[i].lower;
00309 sum2 += ts->data[i].lower * ts->data[i].lower;
00310 sum += ts->data[i].upper;
00311 sum2 += ts->data[i].upper * ts->data[i].upper;
00312 }
00313 avg= (sum / (2.0*norm));
00314
00315 return sqrt(sum2 / (2.0*norm) - avg * avg);
00316 }
00317
00321 Datum ts_mean(PG_FUNCTION_ARGS){
00322 float4 res;
00323 TS *ts = PG_GETARG_TS(0);
00324 res=i_ts_mean(ts);
00325
00326 PG_FREE_IF_COPY(ts, 0);
00327 PG_RETURN_FLOAT4(res);
00328 }
00329
00330
00331 void ts_shift(TS *ts, float4 shift,TS *result){
00332 int i;
00333 int length = ts->length;
00334
00335 result->duration=ts->duration;
00336 for(i=0;i<length;i++){
00337 result->data[i].lower=ts->data[i].lower+shift;
00338 result->data[i].upper=ts->data[i].upper+shift;
00339 }
00340 }
00341
00342 void ts_scale(TS *ts, float4 scale,TS *result){
00343 int i;
00344 int length = ts->length;
00345
00346 result->duration=ts->duration;
00347 for(i=0;i<length;i++){
00348 result->data[i].lower=ts->data[i].lower*scale;
00349 result->data[i].upper=ts->data[i].upper*scale;
00350 }
00351 }
00352
00356 Datum ts_std(PG_FUNCTION_ARGS){
00357 float4 res;
00358 TS *ts = PG_GETARG_TS(0);
00359 res=i_ts_std(ts);
00360
00361 PG_FREE_IF_COPY(ts, 0);
00362 PG_RETURN_FLOAT4(res);
00363 }
00364
00368 Datum ts_add(PG_FUNCTION_ARGS){
00369 TS *ts = PG_GETARG_TS(0);
00370 float4 shift=PG_GETARG_FLOAT4(1);
00371 TS *result;
00372 int length;
00373 int size;
00374
00375 length = ts->length;
00376 size = SIZE_OF_TS(length);
00377 result = palloc0(size);
00378 SET_VARSIZE(result, size);
00379 result->length = length;
00380 ts_shift(ts,shift,result);
00381
00382 PG_FREE_IF_COPY(ts, 0);
00383 PG_RETURN_TS(result);
00384 }
00385
00389 Datum ts_subtract(PG_FUNCTION_ARGS){
00390 TS *ts = PG_GETARG_TS(0);
00391 float4 shift=PG_GETARG_FLOAT4(1);
00392 TS *result;
00393 int length;
00394 int size;
00395
00396 length = ts->length;
00397 size = SIZE_OF_TS(length);
00398 result = palloc0(size);
00399 SET_VARSIZE(result, size);
00400 result->length = length;
00401 shift *=-1.0;
00402 ts_shift(ts,shift,result);
00403
00404 PG_FREE_IF_COPY(ts, 0);
00405 PG_RETURN_TS(result);
00406 }
00407
00411 Datum ts_multiply(PG_FUNCTION_ARGS){
00412 TS *ts = PG_GETARG_TS(0);
00413 float4 scale=PG_GETARG_FLOAT4(1);
00414 TS *result;
00415 int length;
00416 int size;
00417
00418 length = ts->length;
00419 size = SIZE_OF_TS(length);
00420 result = palloc0(size);
00421 SET_VARSIZE(result, size);
00422 result->length = length;
00423 ts_scale(ts,scale,result);
00424
00425 PG_FREE_IF_COPY(ts, 0);
00426 PG_RETURN_TS(result);
00427 }
00428
00429 void i_ts_subset(TS* ts,int32 offset,TS* result){
00430 int i=0;
00431 int j=offset;
00432 while(j<0 && i<result->length){
00433 result->data[i].upper=0;
00434 result->data[i].lower=1;
00435 i++;
00436 j++;
00437 }
00438 while(j<ts->length && i<result->length){
00439 result->data[i].upper=ts->data[j].upper;
00440 result->data[i].lower=ts->data[j].lower;
00441 i++;
00442 j++;
00443 }
00444 while(i<result->length){
00445 result->data[i].upper=0;
00446 result->data[i].lower=1;
00447 i++;
00448 }
00449 }
00450
00451 Datum ts_subset(PG_FUNCTION_ARGS){
00452 TS *ts = PG_GETARG_TS(0);
00453 int32 offset=PG_GETARG_UINT32(1);
00454 int32 length=PG_GETARG_UINT32(2);
00455 TS *result;
00456 int size;
00457
00458 size = SIZE_OF_TS(length);
00459 result = palloc0(size);
00460 SET_VARSIZE(result, size);
00461 result->length = length;
00462 result->duration=(length-1)*(ts->duration/(ts->length-1));
00463 i_ts_subset(ts,offset,result);
00464
00465 PG_FREE_IF_COPY(ts, 0);
00466 PG_RETURN_TS(result);
00467 }
00468
00472 Datum ts_divide(PG_FUNCTION_ARGS){
00473 TS *ts = PG_GETARG_TS(0);
00474 float4 scale=PG_GETARG_FLOAT4(1);
00475 TS *result;
00476 int length;
00477 int size;
00478
00479 length = ts->length;
00480 size = SIZE_OF_TS(length);
00481 result = palloc0(size);
00482 SET_VARSIZE(result, size);
00483 result->length = length;
00484 ts_scale(ts,(1.0/scale),result);
00485
00486 PG_FREE_IF_COPY(ts, 0);
00487 PG_RETURN_TS(result);
00488 }
00489
00490 void
00491 i_ts_sax(TS *ts, int32 sax_len,SAX *result)
00492 {
00493
00494
00495 int length = ts->length;
00496
00497
00498 int size, i;
00499 float min = HUGE;
00500 float max = -HUGE;
00501 int j, k, n, iw;
00502 double avg, std, sum, sum2, norm, mw_l,mw_u;
00503
00504 result->length = sax_len;
00505 result->points_per_letter = (float)length/((float)sax_len);
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 avg= i_ts_mean(ts);
00529 std= i_ts_std(ts);
00530
00531 if (length % sax_len == 0) {
00532 n = length / sax_len;
00533 iw = 0;
00534 for (i = 0; i < sax_len; i++) {
00535 mw_l = 0.0;
00536 mw_u = 0.0;
00537 for (k = 0; k < n; k++) {
00538 mw_l += (ts->data[iw].lower - avg) / std;
00539 mw_u += (ts->data[iw].upper - avg) / std;
00540 iw++;
00541 }
00542
00543 result->data[i].cardinality = DEFAULT_CARDINALITY;
00544 result->data[i].lower = to_base_sax(mw_l / (double) n);
00545 result->data[i].upper = to_base_sax(mw_u / (double) n);
00546 }
00547 } else {
00548 n = 0;
00549 iw = 0;
00550 for (i = 0; i < sax_len; i++) {
00551 mw_l = 0.0;
00552 mw_u = 0.0;
00553 for (k = 0; k < length; k++) {
00554 mw_l += (ts->data[n].lower - avg) / std;
00555 mw_u += (ts->data[n].upper - avg) / std;
00556 iw++;
00557 if (iw == sax_len) {
00558 n++;
00559 iw = 0;
00560 }
00561 }
00562
00563 result->data[i].cardinality = DEFAULT_CARDINALITY;
00564 result->data[i].lower = to_base_sax(mw_l / (double) length);
00565 result->data[i].upper = to_base_sax(mw_u / (double) length);
00566 }
00567 }
00568
00569
00570
00571
00572 }
00573
00574 unsigned char to_base_sax(double val){
00575 unsigned char k = 0;
00576
00577
00578 while ((k < 255) && (val > bp256[k])){
00579
00580 k++;
00581 }
00582
00583 return k;
00584
00585 }
00586