/* * Examine parameters and prepare for a sample scan. */ static void system_time_beginsamplescan(SampleScanState *node, Datum *params, int nparams, uint32 seed) { SystemTimeSamplerData *sampler = (SystemTimeSamplerData *) node->tsm_state; double millis = DatumGetFloat8(params[0]); if (millis < 0 || isnan(millis)) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLESAMPLE_ARGUMENT), errmsg("sample collection time must not be negative"))); sampler->seed = seed; sampler->millis = millis; sampler->lt = InvalidOffsetNumber; sampler->doneblocks = 0; /* start_time, lb will be initialized during first NextSampleBlock call */ /* we intentionally do not change nblocks/firstblock/step here */ }
Datum smithwaterman_op(PG_FUNCTION_ARGS) { float8 res; /* * store *_is_normalized value temporarily 'cause * threshold (we're comparing against) is normalized */ bool tmp = pgs_sw_is_normalized; pgs_sw_is_normalized = true; res = DatumGetFloat8(DirectFunctionCall2( smithwaterman, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1))); /* we're done; back to the previous value */ pgs_sw_is_normalized = tmp; PG_RETURN_BOOL(res >= pgs_sw_threshold); }
static void fetch_restrict(HeapTuple *tuple, TupleDesc *tupdesc, restrict_columns_t *restrict_columns, restrict_t *rest) { Datum binval; bool isnull; int t; for(t=0; t<MAX_RULE_LENGTH;++t) rest->via[t] = -1; binval = SPI_getbinval(*tuple, *tupdesc, restrict_columns->target_id, &isnull); if (isnull) elog(ERROR, "target_id contains a null value"); rest->target_id = DatumGetInt32(binval); binval = SPI_getbinval(*tuple, *tupdesc, restrict_columns->to_cost, &isnull); if (isnull) elog(ERROR, "to_cost contains a null value"); rest->to_cost = DatumGetFloat8(binval); char *str = DatumGetCString(SPI_getvalue(*tuple, *tupdesc, restrict_columns->via_path)); //PGR_DBG("restriction: %f, %i, %s", rest->to_cost, rest->target_id, str); if (str != NULL) { char* pch = NULL; int ci = 0; pch = (char *)strtok (str," ,"); while (pch != NULL && ci < MAX_RULE_LENGTH) { rest->via[ci] = atoi(pch); //PGR_DBG(" rest->via[%i]=%i", ci, rest->via[ci]); ci++; pch = (char *)strtok (NULL, " ,"); } } }
static void fetch_edge_astar(HeapTuple *tuple, TupleDesc *tupdesc, edge_astar_columns_t *edge_columns, edge_astar_t *target_edge) { Datum binval; bool isnull; binval = SPI_getbinval(*tuple, *tupdesc, edge_columns->id, &isnull); if (isnull) elog(ERROR, "id contains a null value"); target_edge->id = DatumGetInt32(binval); binval = SPI_getbinval(*tuple, *tupdesc, edge_columns->source, &isnull); if (isnull) elog(ERROR, "source contains a null value"); target_edge->source = DatumGetInt32(binval); binval = SPI_getbinval(*tuple, *tupdesc, edge_columns->target, &isnull); if (isnull) elog(ERROR, "target contains a null value"); target_edge->target = DatumGetInt32(binval); binval = SPI_getbinval(*tuple, *tupdesc, edge_columns->cost, &isnull); if (isnull) elog(ERROR, "cost contains a null value"); target_edge->cost = DatumGetFloat8(binval); if (edge_columns->reverse_cost != -1) { binval = SPI_getbinval(*tuple, *tupdesc, edge_columns->reverse_cost, &isnull); if (isnull) elog(ERROR, "reverse_cost contains a null value"); target_edge->reverse_cost = DatumGetFloat8(binval); } binval = SPI_getbinval(*tuple, *tupdesc, edge_columns->s_x, &isnull); if (isnull) elog(ERROR, "source x contains a null value"); target_edge->s_x = DatumGetFloat8(binval); binval = SPI_getbinval(*tuple, *tupdesc, edge_columns->s_y, &isnull); if (isnull) elog(ERROR, "source y contains a null value"); target_edge->s_y = DatumGetFloat8(binval); binval = SPI_getbinval(*tuple, *tupdesc, edge_columns->t_x, &isnull); if (isnull) elog(ERROR, "target x contains a null value"); target_edge->t_x = DatumGetFloat8(binval); binval = SPI_getbinval(*tuple, *tupdesc, edge_columns->t_y, &isnull); if (isnull) elog(ERROR, "target y contains a null value"); target_edge->t_y = DatumGetFloat8(binval); }
/* * Binary search on length histogram. Returns greatest index of range length in * histogram which is less than (less than or equal) the given length value. If * all lengths in the histogram are greater than (greater than or equal) the * given length, returns -1. */ static int length_hist_bsearch(Datum *length_hist_values, int length_hist_nvalues, double value, bool equal) { int lower = -1, upper = length_hist_nvalues - 1, middle; while (lower < upper) { double middleval; middle = (lower + upper + 1) / 2; middleval = DatumGetFloat8(length_hist_values[middle]); if (middleval < value || (equal && middleval <= value)) lower = middle; else upper = middle - 1; } return lower; }
Datum regress_dist_ptpath(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); PATH *path = PG_GETARG_PATH_P(1); float8 result = 0.0; /* keep compiler quiet */ float8 tmp; int i; LSEG lseg; switch (path->npts) { case 0: PG_RETURN_NULL(); case 1: result = point_dt(pt, &path->p[0]); break; default: /* * the distance from a point to a path is the smallest distance * from the point to any of its constituent segments. */ Assert(path->npts > 1); for (i = 0; i < path->npts - 1; ++i) { regress_lseg_construct(&lseg, &path->p[i], &path->p[i + 1]); tmp = DatumGetFloat8(DirectFunctionCall2(dist_ps, PointPGetDatum(pt), LsegPGetDatum(&lseg))); if (i == 0 || tmp < result) result = tmp; } break; } PG_RETURN_FLOAT8(result); }
Datum regress_path_dist(PG_FUNCTION_ARGS) { PATH *p1 = PG_GETARG_PATH_P(0); PATH *p2 = PG_GETARG_PATH_P(1); bool have_min = false; float8 min = 0.0; /* initialize to keep compiler quiet */ float8 tmp; int i, j; LSEG seg1, seg2; for (i = 0; i < p1->npts - 1; i++) { for (j = 0; j < p2->npts - 1; j++) { regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]); regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]); tmp = DatumGetFloat8(DirectFunctionCall2(lseg_distance, LsegPGetDatum(&seg1), LsegPGetDatum(&seg2))); if (!have_min || tmp < min) { min = tmp; have_min = true; } } } if (!have_min) PG_RETURN_NULL(); PG_RETURN_FLOAT8(min); }
Datum spg_kd_choose(PG_FUNCTION_ARGS) { spgChooseIn *in = (spgChooseIn *) PG_GETARG_POINTER(0); spgChooseOut *out = (spgChooseOut *) PG_GETARG_POINTER(1); Point *inPoint = DatumGetPointP(in->datum); double coord; if (in->allTheSame) elog(ERROR, "allTheSame should not occur for k-d trees"); Assert(in->hasPrefix); coord = DatumGetFloat8(in->prefixDatum); Assert(in->nNodes == 2); out->resultType = spgMatchNode; out->result.matchNode.nodeN = (getSide(coord, in->level % 2, inPoint) > 0) ? 0 : 1; out->result.matchNode.levelAdd = 1; out->result.matchNode.restDatum = PointPGetDatum(inPoint); PG_RETURN_VOID(); }
/* * Add an attribute to the hash calculation. * **IMPORTANT: any new hard coded support for a data type in here * must be added to isGreenplumDbHashable() below! * * Note that the caller should provide the base type if the datum is * of a domain type. It is quite expensive to call get_typtype() and * getBaseType() here since this function gets called a lot for the * same set of Datums. * * @param hashFn called to update the hash value. * @param clientData passed to hashFn. */ void hashDatum(Datum datum, Oid type, datumHashFunction hashFn, void *clientData) { void *buf = NULL; /* pointer to the data */ size_t len = 0; /* length for the data buffer */ int64 intbuf; /* an 8 byte buffer for all integer sizes */ float4 buf_f4; float8 buf_f8; Timestamp tsbuf; /* timestamp data dype is either a double or * int8 (determined in compile time) */ TimestampTz tstzbuf; DateADT datebuf; TimeADT timebuf; TimeTzADT *timetzptr; Interval *intervalptr; AbsoluteTime abstime_buf; RelativeTime reltime_buf; TimeInterval tinterval; AbsoluteTime tinterval_len; Numeric num; bool bool_buf; char char_buf; Name namebuf; ArrayType *arrbuf; inet *inetptr; /* inet/cidr */ unsigned char inet_hkey[sizeof(inet_struct)]; macaddr *macptr; /* MAC address */ VarBit *vbitptr; int2vector *i2vec_buf; oidvector *oidvec_buf; Cash cash_buf; AclItem *aclitem_ptr; uint32 aclitem_buf; /* * special case buffers */ uint32 nanbuf; uint32 invalidbuf; void *tofree = NULL; /* * Select the hash to be performed according to the field type we are adding to the * hash. */ switch (type) { /* * ======= NUMERIC TYPES ======== */ case INT2OID: /* -32 thousand to 32 thousand, 2-byte storage */ intbuf = (int64) DatumGetInt16(datum); /* cast to 8 byte before * hashing */ buf = &intbuf; len = sizeof(intbuf); break; case INT4OID: /* -2 billion to 2 billion integer, 4-byte * storage */ intbuf = (int64) DatumGetInt32(datum); /* cast to 8 byte before * hashing */ buf = &intbuf; len = sizeof(intbuf); break; case INT8OID: /* ~18 digit integer, 8-byte storage */ intbuf = DatumGetInt64(datum); /* cast to 8 byte before * hashing */ buf = &intbuf; len = sizeof(intbuf); break; case FLOAT4OID: /* single-precision floating point number, * 4-byte storage */ buf_f4 = DatumGetFloat4(datum); /* * On IEEE-float machines, minus zero and zero have different bit * patterns but should compare as equal. We must ensure that they * have the same hash value, which is most easily done this way: */ if (buf_f4 == (float4) 0) buf_f4 = 0.0; buf = &buf_f4; len = sizeof(buf_f4); break; case FLOAT8OID: /* double-precision floating point number, * 8-byte storage */ buf_f8 = DatumGetFloat8(datum); /* * On IEEE-float machines, minus zero and zero have different bit * patterns but should compare as equal. We must ensure that they * have the same hash value, which is most easily done this way: */ if (buf_f8 == (float8) 0) buf_f8 = 0.0; buf = &buf_f8; len = sizeof(buf_f8); break; case NUMERICOID: num = DatumGetNumeric(datum); if (NUMERIC_IS_NAN(num)) { nanbuf = NAN_VAL; buf = &nanbuf; len = sizeof(nanbuf); } else /* not a nan */ { buf = num->n_data; len = (VARSIZE(num) - NUMERIC_HDRSZ); } /* * If we did a pg_detoast_datum, we need to remember to pfree, * or we will leak memory. Because of the 1-byte varlena header stuff. */ if (num != DatumGetPointer(datum)) tofree = num; break; /* * ====== CHARACTER TYPES ======= */ case CHAROID: /* char(1), single character */ char_buf = DatumGetChar(datum); buf = &char_buf; len = 1; break; case BPCHAROID: /* char(n), blank-padded string, fixed storage */ case TEXTOID: /* text */ case VARCHAROID: /* varchar */ case BYTEAOID: /* bytea */ { int tmplen; varattrib_untoast_ptr_len(datum, (char **) &buf, &tmplen, &tofree); /* adjust length to not include trailing blanks */ if (type != BYTEAOID && tmplen > 1) tmplen = ignoreblanks((char *) buf, tmplen); len = tmplen; break; } case NAMEOID: namebuf = DatumGetName(datum); len = NAMEDATALEN; buf = NameStr(*namebuf); /* adjust length to not include trailing blanks */ if (len > 1) len = ignoreblanks((char *) buf, len); break; /* * ====== OBJECT IDENTIFIER TYPES ====== */ case OIDOID: /* object identifier(oid), maximum 4 billion */ case REGPROCOID: /* function name */ case REGPROCEDUREOID: /* function name with argument types */ case REGOPEROID: /* operator name */ case REGOPERATOROID: /* operator with argument types */ case REGCLASSOID: /* relation name */ case REGTYPEOID: /* data type name */ intbuf = (int64) DatumGetUInt32(datum); /* cast to 8 byte before hashing */ buf = &intbuf; len = sizeof(intbuf); break; case TIDOID: /* tuple id (6 bytes) */ buf = DatumGetPointer(datum); len = SizeOfIptrData; break; /* * ====== DATE/TIME TYPES ====== */ case TIMESTAMPOID: /* date and time */ tsbuf = DatumGetTimestamp(datum); buf = &tsbuf; len = sizeof(tsbuf); break; case TIMESTAMPTZOID: /* date and time with time zone */ tstzbuf = DatumGetTimestampTz(datum); buf = &tstzbuf; len = sizeof(tstzbuf); break; case DATEOID: /* ANSI SQL date */ datebuf = DatumGetDateADT(datum); buf = &datebuf; len = sizeof(datebuf); break; case TIMEOID: /* hh:mm:ss, ANSI SQL time */ timebuf = DatumGetTimeADT(datum); buf = &timebuf; len = sizeof(timebuf); break; case TIMETZOID: /* time with time zone */ /* * will not compare to TIMEOID on equal values. * Postgres never attempts to compare the two as well. */ timetzptr = DatumGetTimeTzADTP(datum); buf = (unsigned char *) timetzptr; /* * Specify hash length as sizeof(double) + sizeof(int4), not as * sizeof(TimeTzADT), so that any garbage pad bytes in the structure * won't be included in the hash! */ len = sizeof(timetzptr->time) + sizeof(timetzptr->zone); break; case INTERVALOID: /* @ <number> <units>, time interval */ intervalptr = DatumGetIntervalP(datum); buf = (unsigned char *) intervalptr; /* * Specify hash length as sizeof(double) + sizeof(int4), not as * sizeof(Interval), so that any garbage pad bytes in the structure * won't be included in the hash! */ len = sizeof(intervalptr->time) + sizeof(intervalptr->month); break; case ABSTIMEOID: abstime_buf = DatumGetAbsoluteTime(datum); if (abstime_buf == INVALID_ABSTIME) { /* hash to a constant value */ invalidbuf = INVALID_VAL; len = sizeof(invalidbuf); buf = &invalidbuf; } else { len = sizeof(abstime_buf); buf = &abstime_buf; } break; case RELTIMEOID: reltime_buf = DatumGetRelativeTime(datum); if (reltime_buf == INVALID_RELTIME) { /* hash to a constant value */ invalidbuf = INVALID_VAL; len = sizeof(invalidbuf); buf = &invalidbuf; } else { len = sizeof(reltime_buf); buf = &reltime_buf; } break; case TINTERVALOID: tinterval = DatumGetTimeInterval(datum); /* * check if a valid interval. the '0' status code * stands for T_INTERVAL_INVAL which is defined in * nabstime.c. We use the actual value instead * of defining it again here. */ if(tinterval->status == 0 || tinterval->data[0] == INVALID_ABSTIME || tinterval->data[1] == INVALID_ABSTIME) { /* hash to a constant value */ invalidbuf = INVALID_VAL; len = sizeof(invalidbuf); buf = &invalidbuf; } else { /* normalize on length of the time interval */ tinterval_len = tinterval->data[1] - tinterval->data[0]; len = sizeof(tinterval_len); buf = &tinterval_len; } break; /* * ======= NETWORK TYPES ======== */ case INETOID: case CIDROID: inetptr = DatumGetInetP(datum); len = inet_getkey(inetptr, inet_hkey, sizeof(inet_hkey)); /* fill-in inet_key & get len */ buf = inet_hkey; break; case MACADDROID: macptr = DatumGetMacaddrP(datum); len = sizeof(macaddr); buf = (unsigned char *) macptr; break; /* * ======== BIT STRINGS ======== */ case BITOID: case VARBITOID: /* * Note that these are essentially strings. * we don't need to worry about '10' and '010' * to compare, b/c they will not, by design. * (see SQL standard, and varbit.c) */ vbitptr = DatumGetVarBitP(datum); len = VARBITBYTES(vbitptr); buf = (char *) VARBITS(vbitptr); break; /* * ======= other types ======= */ case BOOLOID: /* boolean, 'true'/'false' */ bool_buf = DatumGetBool(datum); buf = &bool_buf; len = sizeof(bool_buf); break; /* * We prepare the hash key for aclitems just like postgresql does. * (see code and comment in acl.c: hash_aclitem() ). */ case ACLITEMOID: aclitem_ptr = DatumGetAclItemP(datum); aclitem_buf = (uint32) (aclitem_ptr->ai_privs + aclitem_ptr->ai_grantee + aclitem_ptr->ai_grantor); buf = &aclitem_buf; len = sizeof(aclitem_buf); break; /* * ANYARRAY is a pseudo-type. We use it to include * any of the array types (OIDs 1007-1033 in pg_type.h). * caller needs to be sure the type is ANYARRAYOID * before calling cdbhash on an array (INSERT and COPY do so). */ case ANYARRAYOID: arrbuf = DatumGetArrayTypeP(datum); len = VARSIZE(arrbuf) - VARHDRSZ; buf = VARDATA(arrbuf); break; case INT2VECTOROID: i2vec_buf = (int2vector *) DatumGetPointer(datum); len = i2vec_buf->dim1 * sizeof(int2); buf = (void *)i2vec_buf->values; break; case OIDVECTOROID: oidvec_buf = (oidvector *) DatumGetPointer(datum); len = oidvec_buf->dim1 * sizeof(Oid); buf = oidvec_buf->values; break; case CASHOID: /* cash is stored in int32 internally */ cash_buf = (* (Cash *)DatumGetPointer(datum)); len = sizeof(Cash); buf = &cash_buf; break; default: ereport(ERROR, (errcode(ERRCODE_CDB_FEATURE_NOT_YET), errmsg("Type %u is not hashable.", type))); } /* switch(type) */ /* do the hash using the selected algorithm */ hashFn(clientData, buf, len); if(tofree) pfree(tofree); }
Datum generate_sparse_vector(PG_FUNCTION_ARGS) { SvecType *output_sfv; int16_t typlen; bool typbyval; char typalign; bool *nulls; if (PG_NARGS() != 3) elog(ERROR, "Invalid number of arguments."); ArrayType *term_index = PG_GETARG_ARRAYTYPE_P(0); ArrayType *term_count = PG_GETARG_ARRAYTYPE_P(1); int64_t dict_size = PG_GETARG_INT64(2); /* Check if arrays have null entries */ if (ARR_HASNULL(term_index) || ARR_HASNULL(term_count)) elog(ERROR, "One or both of the argument arrays has one or more null entries."); if (dict_size <= 0) elog(ERROR, "Dictionary size cannot be zero or negative."); /* Check if any of the argument arrays is empty */ if ((ARR_NDIM(term_index) == 0) || (ARR_NDIM(term_count) == 0)) elog(ERROR, "One or more argument arrays is empty."); int term_index_nelems = ARR_DIMS(term_index)[0]; int term_count_nelems = ARR_DIMS(term_count)[0]; /* If no. of elements in the arrays are not equal, throw an error */ if (term_index_nelems != term_count_nelems) elog(ERROR, "No. of elements in the argument arrays are not equal."); Datum *term_index_data; Datum *term_count_data; /* Deconstruct the arrays */ get_typlenbyvalalign(INT8OID, &typlen, &typbyval, &typalign); deconstruct_array(term_index, INT8OID, typlen, typbyval, typalign, &term_index_data, &nulls, &term_index_nelems); get_typlenbyvalalign(FLOAT8OID, &typlen, &typbyval, &typalign); deconstruct_array(term_count, FLOAT8OID, typlen, typbyval, typalign, &term_count_data, &nulls, &term_count_nelems); /* Check if term index array has indexes in proper order or not */ for(int i = 0; i < term_index_nelems; i++) { if (DatumGetInt64(term_index_data[i]) < 0 || DatumGetInt64(term_index_data[i]) >= dict_size) elog(ERROR, "Term indexes must range from 0 to total number of elements in the dictonary - 1."); } float8 *histogram = (float8 *)palloc0(sizeof(float8) * dict_size); for (int k = 0; k < dict_size; k++) { histogram[k] = 0; } for (int i = 0; i < term_index_nelems; i++) { uint64_t idx = DatumGetInt64(term_index_data[i]); histogram[idx] += DatumGetFloat8(term_count_data[i]); } output_sfv = svec_from_float8arr(histogram, dict_size); pfree(histogram); PG_RETURN_POINTER(output_sfv); }
GISTENTRY * gbt_num_compress(GISTENTRY *retval, GISTENTRY *entry, const gbtree_ninfo *tinfo) { if (entry->leafkey) { union { int16 i2; int32 i4; int64 i8; float4 f4; float8 f8; DateADT dt; TimeADT tm; Timestamp ts; Cash ch; } v; GBT_NUMKEY *r = (GBT_NUMKEY *) palloc0(2 * tinfo->size); void *leaf = NULL; switch (tinfo->t) { case gbt_t_int2: v.i2 = DatumGetInt16(entry->key); leaf = &v.i2; break; case gbt_t_int4: v.i4 = DatumGetInt32(entry->key); leaf = &v.i4; break; case gbt_t_int8: v.i8 = DatumGetInt64(entry->key); leaf = &v.i8; break; case gbt_t_oid: v.i4 = DatumGetObjectId(entry->key); leaf = &v.i4; break; case gbt_t_float4: v.f4 = DatumGetFloat4(entry->key); leaf = &v.f4; break; case gbt_t_float8: v.f8 = DatumGetFloat8(entry->key); leaf = &v.f8; break; case gbt_t_date: v.dt = DatumGetDateADT(entry->key); leaf = &v.dt; break; case gbt_t_time: v.tm = DatumGetTimeADT(entry->key); leaf = &v.tm; break; case gbt_t_ts: v.ts = DatumGetTimestamp(entry->key); leaf = &v.ts; break; case gbt_t_cash: v.ch = DatumGetCash(entry->key); leaf = &v.ch; break; default: leaf = DatumGetPointer(entry->key); } memcpy((void *) &r[0], leaf, tinfo->size); memcpy((void *) &r[tinfo->size], leaf, tinfo->size); retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page, entry->offset, FALSE); } else retval = entry; return retval; }
void ParquetColumnReader_readPATH( ParquetColumnReader readers[], Datum *value, bool *null) { PATH *path; Datum child_values[3] = {0}; /* is_open, points.x, points.y */ bool child_nulls[3] = {0}; int npts, maxnpts; ParquetColumnReader_readValue(&readers[0], &child_values[0], &child_nulls[0], HAWQ_TYPE_BOOL); if (child_nulls[0]) { ParquetColumnReader_readValue(&readers[1], &child_values[1], &child_nulls[1], HAWQ_TYPE_FLOAT8); ParquetColumnReader_readValue(&readers[2], &child_values[2], &child_nulls[2], HAWQ_TYPE_FLOAT8); Insist(child_nulls[1] && child_nulls[2]); *null = true; return; } npts = 0; path = readers[0].geoval; if (path == NULL) { maxnpts = 10; path = (PATH *)palloc0(get_path_size(maxnpts)); } else { maxnpts = path->npts; } path->closed = !DatumGetBool(child_values[0]); while (true) { if (npts >= maxnpts) { maxnpts *= 2; path = (PATH *)repalloc(path, get_path_size(maxnpts)); } ParquetColumnReader_readValue(&readers[1], &child_values[1], &child_nulls[1], HAWQ_TYPE_FLOAT8); ParquetColumnReader_readValue(&readers[2], &child_values[2], &child_nulls[2], HAWQ_TYPE_FLOAT8); path->p[npts].x = DatumGetFloat8(child_values[1]); path->p[npts].y = DatumGetFloat8(child_values[2]); npts++; if (NextRepetitionLevel(&readers[1]) == 0) break; /* no more points in this path */ } path = (PATH *)repalloc(path, get_path_size(npts)); SET_VARSIZE(path, get_path_size(npts)); path->npts = npts; *value = PointerGetDatum(path); *null = false; readers[0].geoval = path; }
Datum gbt_numeric_penalty(PG_FUNCTION_ARGS) { GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1); float *result = (float *) PG_GETARG_POINTER(2); Numeric us, os, ds; GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key); GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key); Datum uni; GBT_VARKEY_R rk, ok, uk; rk = gbt_var_key_readable(org); uni = PointerGetDatum(gbt_var_key_copy(&rk, TRUE)); gbt_var_bin_union(&uni, newe, &tinfo); ok = gbt_var_key_readable(org); uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni)); us = DatumGetNumeric(DirectFunctionCall2( numeric_sub, PointerGetDatum(uk.upper), PointerGetDatum(uk.lower) )); os = DatumGetNumeric(DirectFunctionCall2( numeric_sub, PointerGetDatum(ok.upper), PointerGetDatum(ok.lower) )); ds = DatumGetNumeric(DirectFunctionCall2( numeric_sub, NumericGetDatum(us), NumericGetDatum(os) )); if (numeric_is_nan(us)) { if (numeric_is_nan(os)) *result = 0.0; else *result = 1.0; } else { Numeric nul = DatumGetNumeric(DirectFunctionCall1(int4_numeric, Int32GetDatum(0))); *result = 0.0; if (DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul))) { *result += FLT_MIN; os = DatumGetNumeric(DirectFunctionCall2( numeric_div, NumericGetDatum(ds), NumericGetDatum(us) )); *result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os))); } } if (*result > 0) *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1)); PG_RETURN_POINTER(result); }
static jvalue _Double_coerceDatum(Type self, Datum arg) { jvalue result; result.l = JNI_newObject(s_Double_class, s_Double_init, DatumGetFloat8(arg)); return result; }
static jvalue _double_coerceDatum(Type self, Datum arg) { jvalue result; result.d = DatumGetFloat8(arg); return result; }
double getNextValue(ModelInfo *model, int num) { return DatumGetFloat8(FunctionCall2(&model->algInfo->algGetNextValue,PointerGetDatum(model->model),Int32GetDatum(num))); }
static DTYPE *get_pgarray(int *num, ArrayType *input) { int ndims, *dims, *lbs; bool *nulls; Oid i_eltype; int16 i_typlen; bool i_typbyval; char i_typalign; Datum *i_data; int i, n; DTYPE *data; /* get input array element type */ i_eltype = ARR_ELEMTYPE(input); get_typlenbyvalalign(i_eltype, &i_typlen, &i_typbyval, &i_typalign); /* validate input data type */ switch(i_eltype) { case INT2OID: case INT4OID: case FLOAT4OID: case FLOAT8OID: break; default: elog(ERROR, "Invalid input data type"); break; } /* get various pieces of data from the input array */ ndims = ARR_NDIM(input); dims = ARR_DIMS(input); lbs = ARR_LBOUND(input); if (ndims != 2 || dims[0] != dims[1]) { elog(ERROR, "Error: matrix[num][num] in its definition."); } /* get src data */ deconstruct_array(input, i_eltype, i_typlen, i_typbyval, i_typalign, &i_data, &nulls, &n); DBG("get_pgarray: ndims=%d, n=%d", ndims, n); #ifdef DEBUG for (i=0; i<ndims; i++) { DBG(" dims[%d]=%d, lbs[%d]=%d", i, dims[i], i, lbs[i]); } #endif /* construct a C array */ data = (DTYPE *) palloc(n * sizeof(DTYPE)); if (!data) { elog(ERROR, "Error: Out of memory!"); } for (i=0; i<n; i++) { if (nulls[i]) { data[i] = INFINITY; } else { switch(i_eltype) { case INT2OID: data[i] = (DTYPE) DatumGetInt16(i_data[i]); break; case INT4OID: data[i] = (DTYPE) DatumGetInt32(i_data[i]); break; case FLOAT4OID: data[i] = (DTYPE) DatumGetFloat4(i_data[i]); break; case FLOAT8OID: data[i] = (DTYPE) DatumGetFloat8(i_data[i]); break; } /* we assume negative values are INFINTY */ /******************************************************** TODO: based on trying to add an endpt it is likely that this will not work and you will get and error in findEulerianPath **********************************************************/ if (data[i] < 0) data[i] = INFINITY; } DBG(" data[%d]=%.4f", i, data[i]); } pfree(nulls); pfree(i_data); *num = dims[0]; return data; }
/* * Reading quantiles from an input array, based mostly on * array_to_text_internal (it's a modified copy). This expects * to receive a single-dimensional float8 array as input, fails * otherwise. */ static double * array_to_double(FunctionCallInfo fcinfo, ArrayType *v, int * len) { double *result; int nitems, *dims, ndims; Oid element_type; int typlen; bool typbyval; char typalign; char *p; int i, idx = 0; ArrayMetaState *my_extra; ndims = ARR_NDIM(v); dims = ARR_DIMS(v); nitems = ArrayGetNItems(ndims, dims); /* this is a special-purpose function for single-dimensional arrays */ if (ndims != 1) { elog(ERROR, "error, array_to_double expects a single-dimensional array" "(dims = %d)", ndims); } /* if there are no elements, set the length to 0 and return NULL */ if (nitems == 0) { (*len) = 0; return NULL; } element_type = ARR_ELEMTYPE(v); result = (double*)palloc(nitems * sizeof(double)); /* * We arrange to look up info about element type, including its output * conversion proc, only once per series of calls, assuming the element * type doesn't change underneath us. */ my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; if (my_extra == NULL) { fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(ArrayMetaState)); my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; my_extra->element_type = ~element_type; } if (my_extra->element_type != element_type) { /* * Get info about element type, including its output conversion proc */ get_type_io_data(element_type, IOFunc_output, &my_extra->typlen, &my_extra->typbyval, &my_extra->typalign, &my_extra->typdelim, &my_extra->typioparam, &my_extra->typiofunc); fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc, fcinfo->flinfo->fn_mcxt); my_extra->element_type = element_type; } typlen = my_extra->typlen; typbyval = my_extra->typbyval; typalign = my_extra->typalign; p = ARR_DATA_PTR(v); for (i = 0; i < nitems; i++) { Datum itemvalue = fetch_att(p, typbyval, typlen); double val = DatumGetFloat8(itemvalue); result[idx++] = val; p = att_addlength_pointer(p, typlen, p); p = (char *) att_align_nominal(p, typalign); } (*len) = idx; return result; }
int create_spatial_index(sqlite3 *db,char *dataset_name, char *idx_tbl,char * idx_geom, char *idx_id, char *sql_string, int create) { char sql_txt_pg[SQLSTRLEN]; char sql_txt_sqlite[SQLSTRLEN]; int rc; char *err_msg; SPIPlanPtr plan; sqlite3_stmt *prepared_statement; Portal cur; char *pg_type; int val_int, proc,j; float8 val_float; int64 val_int64; bool null_check; TupleDesc tupdesc; SPITupleTable *tuptable; HeapTuple tuple; int tot_rows = 0; if(create) { snprintf(sql_txt_pg,sizeof(sql_txt_pg), " %s%s%s", "CREATE VIRTUAL TABLE ", dataset_name, "_idx_geom USING rtree(id,minX, maxX,minY, maxY)"); rc = sqlite3_exec(db, sql_txt_pg, NULL, 0, &err_msg); if (rc != SQLITE_OK ) { sqlite3_free(err_msg); sqlite3_close(db); ereport(ERROR, ( errmsg("Problem creating table: %s", err_msg))); //fprintf(stderr, "SQL error: %s\n", err_msg); } elog(INFO, "create table string: %s", sql_txt_pg); } snprintf(sql_txt_pg,sizeof(sql_txt_pg), " %s%s%s%s%s%s%s%s%s", "with o as (", sql_string, "), g as( select ", idx_id, " id,", idx_geom, " geom from ", idx_tbl, ") select g.id, st_xmin(g.geom) minx,st_xmax(g.geom) maxx,st_ymin(g.geom) miny,st_ymax(g.geom) maxy from g inner join o on g.id=o.id"); elog(INFO, "select table string: %s", sql_txt_pg); plan = SPI_prepare(sql_txt_pg,0,NULL); //ret = SPI_exec(sql_string, 0); cur = SPI_cursor_open("index_cursor", plan,NULL,NULL,true); snprintf(sql_txt_sqlite,sizeof(sql_txt_sqlite), " %s%s%s", "insert into ", dataset_name, "_idx_geom (id,minX, maxX,minY, maxY) values(?,?,?,?,?)"); elog(INFO, "insert table string: %s", sql_txt_sqlite); sqlite3_prepare_v2(db,sql_txt_sqlite,strlen(sql_txt_sqlite), &prepared_statement,NULL); do { sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &err_msg); SPI_cursor_fetch(cur, true,100000); proc = SPI_processed; tot_rows += proc; // if (ret > 0 && SPI_tuptable != NULL) // { tupdesc = SPI_tuptable->tupdesc; tuptable = SPI_tuptable; for (j = 0; j < proc; j++) { tuple = tuptable->vals[j]; pg_type = SPI_gettype(tupdesc, 1); if(strcmp(pg_type, "int2")==0) { val_int = (int) DatumGetInt16(SPI_getbinval(tuple,tupdesc,1, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, 1); else sqlite3_bind_int(prepared_statement, 1,val_int); } else if(strcmp(pg_type, "int4")==0) { val_int = (int) DatumGetInt32(SPI_getbinval(tuple,tupdesc,1, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, 1); else sqlite3_bind_int(prepared_statement, 1,val_int); } else if(strcmp(pg_type, "int8")==0) { val_int64 = (int64) DatumGetInt64(SPI_getbinval(tuple,tupdesc,1, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, 1); else sqlite3_bind_int64(prepared_statement,1,val_int64); } val_float = (float8) DatumGetFloat8(SPI_getbinval(tuple,tupdesc,2, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, 2); else sqlite3_bind_double(prepared_statement,2,val_float); val_float = (float8) DatumGetFloat8(SPI_getbinval(tuple,tupdesc,3, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, 3); else sqlite3_bind_double(prepared_statement,3,val_float); val_float = (float8) DatumGetFloat8(SPI_getbinval(tuple,tupdesc,4, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, 4); else sqlite3_bind_double(prepared_statement,4,val_float); val_float = (float8) DatumGetFloat8(SPI_getbinval(tuple,tupdesc,5, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, 5); else sqlite3_bind_double(prepared_statement,5,val_float); sqlite3_step(prepared_statement); sqlite3_clear_bindings(prepared_statement); sqlite3_reset(prepared_statement); } sqlite3_exec(db, "END TRANSACTION", NULL, NULL, &err_msg); elog(INFO, "inserted %d rows in index",tot_rows); } while (proc > 0); return 0; }
/* * Get relative position of value in histogram bin in [0,1] range. */ static float8 get_position(TypeCacheEntry *typcache, RangeBound *value, RangeBound *hist1, RangeBound *hist2) { bool has_subdiff = OidIsValid(typcache->rng_subdiff_finfo.fn_oid); float8 position; if (!hist1->infinite && !hist2->infinite) { float8 bin_width; /* * Both bounds are finite. Assuming the subtype's comparison function * works sanely, the value must be finite, too, because it lies * somewhere between the bounds. If it doesn't, just return something. */ if (value->infinite) return 0.5; /* Can't interpolate without subdiff function */ if (!has_subdiff) return 0.5; /* Calculate relative position using subdiff function. */ bin_width = DatumGetFloat8(FunctionCall2Coll( &typcache->rng_subdiff_finfo, typcache->rng_collation, hist2->val, hist1->val)); if (bin_width <= 0.0) return 0.5; /* zero width bin */ position = DatumGetFloat8(FunctionCall2Coll( &typcache->rng_subdiff_finfo, typcache->rng_collation, value->val, hist1->val)) / bin_width; /* Relative position must be in [0,1] range */ position = Max(position, 0.0); position = Min(position, 1.0); return position; } else if (hist1->infinite && !hist2->infinite) { /* * Lower bin boundary is -infinite, upper is finite. If the value is * -infinite, return 0.0 to indicate it's equal to the lower bound. * Otherwise return 1.0 to indicate it's infinitely far from the lower * bound. */ return ((value->infinite && value->lower) ? 0.0 : 1.0); } else if (!hist1->infinite && hist2->infinite) { /* same as above, but in reverse */ return ((value->infinite && !value->lower) ? 1.0 : 0.0); } else { /* * If both bin boundaries are infinite, they should be equal to each * other, and the value should also be infinite and equal to both * bounds. (But don't Assert that, to avoid crashing if a user creates * a datatype with a broken comparison function). * * Assume the value to lie in the middle of the infinite bounds. */ return 0.5; } }
int write2sqlite(char *sqlitedb_name,char *dataset_name, char *sql_string, char *twkb_name,char *id_name,char *idx_geom,char *idx_tbl, char *idx_id, int create) { char *err_msg; int spi_conn; int proc, rc; /*Sqlite*/ sqlite3 *db; TupleDesc tupdesc; SPITupleTable *tuptable; HeapTuple tuple; int i, j; SPIPlanPtr plan; char insert_str[SQLSTRLEN]; Portal cur; void *val_p; int val_int; int64 val_int64; float8 val_float; bool null_check; char *pg_type; int tot_rows = 0; sqlite3_stmt *prepared_statement; spi_conn = SPI_connect(); if (spi_conn!=SPI_OK_CONNECT) ereport(ERROR, ( errmsg("Failed to open SPI Connection"))); /*Open the sqlite db to write to*/ rc = sqlite3_open(sqlitedb_name, &db); if (rc != SQLITE_OK) { sqlite3_close(db); ereport(ERROR, ( errmsg("Cannot open SQLite database"))); } plan = SPI_prepare(sql_string,0,NULL); //ret = SPI_exec(sql_string, 0); cur = SPI_cursor_open("our_cursor", plan,NULL,NULL,true); elog(INFO, "build sql-strings and create table if : %d",create); create_sqlite_table(&cur,db, insert_str,dataset_name,twkb_name, id_name,create); elog(INFO, "back from creating table"); elog(INFO, "inserted sql = %s",insert_str); //TODO add error handling sqlite3_prepare_v2(db,insert_str,strlen(insert_str), &prepared_statement,NULL); do { sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &err_msg); SPI_cursor_fetch(cur, true,10000); proc = SPI_processed; tot_rows += proc; // if (ret > 0 && SPI_tuptable != NULL) // { tupdesc = SPI_tuptable->tupdesc; tuptable = SPI_tuptable; for (j = 0; j < proc; j++) { tuple = tuptable->vals[j]; for (i = 1; i <= tupdesc->natts; i++) { pg_type = SPI_gettype(tupdesc, i); if(strcmp(pg_type, "bool")==0) { val_int = (bool) (DatumGetBool(SPI_getbinval(tuple,tupdesc,i, &null_check)) ? 1:0); if(null_check) sqlite3_bind_null(prepared_statement, i); else sqlite3_bind_int(prepared_statement, i,(int) val_int); } if(strcmp(pg_type, "int2")==0) { val_int = (int) DatumGetInt16(SPI_getbinval(tuple,tupdesc,i, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, i); else sqlite3_bind_int(prepared_statement, i,val_int); } else if(strcmp(pg_type, "int4")==0) { val_int = (int) DatumGetInt32(SPI_getbinval(tuple,tupdesc,i, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, i); else sqlite3_bind_int(prepared_statement, i,val_int); } else if(strcmp(pg_type, "int8")==0) { val_int64 = (int64) DatumGetInt64(SPI_getbinval(tuple,tupdesc,i, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, i); else sqlite3_bind_int64(prepared_statement, i,val_int64); } else if(strcmp(pg_type, "float4")==0) { val_float = (float8) DatumGetFloat4(SPI_getbinval(tuple,tupdesc,i, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, i); else sqlite3_bind_double(prepared_statement, i,val_float); } else if(strcmp(pg_type, "float8")==0) { val_float = (float8) DatumGetFloat8(SPI_getbinval(tuple,tupdesc,i, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, i); else sqlite3_bind_double(prepared_statement, i,val_float); } else if(strcmp(pg_type, "bytea")==0) { val_p = (void*) PG_DETOAST_DATUM(SPI_getbinval(tuple,tupdesc,i, &null_check)); //TODO add error handling if(null_check) sqlite3_bind_null(prepared_statement, i); else sqlite3_bind_blob(prepared_statement, i, (const void*) VARDATA_ANY(val_p), VARSIZE_ANY(val_p)-VARHDRSZ, SQLITE_TRANSIENT); } else { // val = (void*) PG_DETOAST_DATUM(SPI_getbinval(tuple,tupdesc,i, &null_check)); //TODO add error handling sqlite3_bind_text(prepared_statement,i,SPI_getvalue(tuple, tupdesc, i),-1,NULL); } } sqlite3_step(prepared_statement); sqlite3_clear_bindings(prepared_statement); sqlite3_reset(prepared_statement); } sqlite3_exec(db, "END TRANSACTION", NULL, NULL, &err_msg); elog(INFO, "inserted %d rows in table",tot_rows); } while (proc > 0); if(dataset_name && idx_geom && idx_id) create_spatial_index(db,dataset_name,idx_tbl, idx_geom, idx_id, sql_string,create); else elog(INFO, "Finnishing without spatial index"); SPI_finish(); sqlite3_close(db); return 0; }
/** * Returns a histogram from an array of numbers. * by Paul A. Jungwirth */ Datum array_to_hist(PG_FUNCTION_ARGS) { // Our arguments: ArrayType *vals; pgnum bucketsStart; pgnum bucketsSize; int32 bucketsCount; // The array element type: Oid valsType; // The array element type widths for our input and output arrays: int16 valsTypeWidth; int16 histTypeWidth; // The array element type "is passed by value" flags (not really used): bool valsTypeByValue; bool histTypeByValue; // The array element type alignment codes (not really used): char valsTypeAlignmentCode; char histTypeAlignmentCode; // The array contents, as PostgreSQL "Datum" objects: Datum *valsContent; Datum *histContent; // List of "is null" flags for the array contents (not used): bool *valsNullFlags; // The size of the input array: int valsLength; // The output array: ArrayType* histArray; pgnum histMax; pgnum v; int i; if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3)) { ereport(ERROR, (errmsg("Null arguments not accepted"))); } vals = PG_GETARG_ARRAYTYPE_P(0); if (ARR_NDIM(vals) > 1) { ereport(ERROR, (errmsg("One-dimesional arrays are required"))); } if (array_contains_nulls(vals)) { ereport(ERROR, (errmsg("Array contains null elements"))); } // Determine the array element types. valsType = ARR_ELEMTYPE(vals); if (valsType != INT2OID && valsType != INT4OID && valsType != INT8OID && valsType != FLOAT4OID && valsType != FLOAT8OID) { ereport(ERROR, (errmsg("Histogram subject must be SMALLINT, INTEGER, BIGINT, REAL, or DOUBLE PRECISION values"))); } valsLength = (ARR_DIMS(vals))[0]; switch (valsType) { case INT2OID: bucketsStart.i16 = PG_GETARG_INT16(1); bucketsSize.i16 = PG_GETARG_INT16(2); break; case INT4OID: bucketsStart.i32 = PG_GETARG_INT32(1); bucketsSize.i32 = PG_GETARG_INT32(2); break; case INT8OID: bucketsStart.i64 = PG_GETARG_INT64(1); bucketsSize.i64 = PG_GETARG_INT64(2); break; case FLOAT4OID: bucketsStart.f4 = PG_GETARG_FLOAT4(1); bucketsSize.f4 = PG_GETARG_FLOAT4(2); break; case FLOAT8OID: bucketsStart.f8 = PG_GETARG_FLOAT8(1); bucketsSize.f8 = PG_GETARG_FLOAT8(2); break; default: break; } bucketsCount = PG_GETARG_INT32(3); get_typlenbyvalalign(valsType, &valsTypeWidth, &valsTypeByValue, &valsTypeAlignmentCode); // Extract the array contents (as Datum objects). deconstruct_array(vals, valsType, valsTypeWidth, valsTypeByValue, valsTypeAlignmentCode, &valsContent, &valsNullFlags, &valsLength); // Create a new array of histogram bins (as Datum objects). // Memory we palloc is freed automatically at the end of the transaction. histContent = palloc0(sizeof(Datum) * bucketsCount); // Generate the histogram switch (valsType) { case INT2OID: histMax.i16 = bucketsStart.i16 + (bucketsSize.i16 * bucketsCount); for (i = 0; i < valsLength; i++) { v.i16 = DatumGetInt16(valsContent[i]); if (v.i16 >= bucketsStart.i16 && v.i16 <= histMax.i16) { int b = (v.i16 - bucketsStart.i16) / bucketsSize.i16; if (b >= 0 && b < bucketsCount) { histContent[b] = Int32GetDatum(DatumGetInt32(histContent[b]) + 1); } } } break; case INT4OID: histMax.i32 = bucketsStart.i32 + (bucketsSize.i32 * bucketsCount); for (i = 0; i < valsLength; i++) { v.i32 = DatumGetInt32(valsContent[i]); if (v.i32 >= bucketsStart.i32 && v.i32 <= histMax.i32) { int b = (v.i32 - bucketsStart.i32) / bucketsSize.i32; if (b >= 0 && b < bucketsCount) { histContent[b] = Int32GetDatum(DatumGetInt32(histContent[b]) + 1); } } } break; case INT8OID: histMax.i64 = bucketsStart.i64 + (bucketsSize.i64 * bucketsCount); for (i = 0; i < valsLength; i++) { v.i64 = DatumGetInt64(valsContent[i]); if (v.i64 >= bucketsStart.i64 && v.i64 <= histMax.i64) { int b = (v.i64 - bucketsStart.i64) / bucketsSize.i64; if (b >= 0 && b < bucketsCount) { histContent[b] = Int64GetDatum(DatumGetInt64(histContent[b]) + 1); } } } break; case FLOAT4OID: histMax.f4 = bucketsStart.f4 + (bucketsSize.f4 * bucketsCount); for (i = 0; i < valsLength; i++) { v.f4 = DatumGetFloat4(valsContent[i]); if (v.f4 >= bucketsStart.f4 && v.f4 <= histMax.f4) { int b = (v.f4 - bucketsStart.f4) / bucketsSize.f4; if (b >= 0 && b < bucketsCount) { histContent[b] = Int32GetDatum(DatumGetInt32(histContent[b]) + 1); } } } break; case FLOAT8OID: histMax.f8 = bucketsStart.f8 + (bucketsSize.f8 * bucketsCount); for (i = 0; i < valsLength; i++) { v.f8 = DatumGetFloat8(valsContent[i]); if (v.f8 >= bucketsStart.f8 && v.f8 <= histMax.f8) { int b = (v.f8 - bucketsStart.f8) / bucketsSize.f8; if (b >= 0 && b < bucketsCount) { histContent[b] = Int32GetDatum(DatumGetInt32(histContent[b]) + 1); } } } break; default: break; } // Wrap the buckets in a new PostgreSQL array object. get_typlenbyvalalign(INT4OID, &histTypeWidth, &histTypeByValue, &histTypeAlignmentCode); histArray = construct_array(histContent, bucketsCount, INT4OID, histTypeWidth, histTypeByValue, histTypeAlignmentCode); // Return the final PostgreSQL array object. PG_RETURN_ARRAYTYPE_P(histArray); }
/* * gistindex_keytest() -- does this index tuple satisfy the scan key(s)? * * The index tuple might represent either a heap tuple or a lower index page, * depending on whether the containing page is a leaf page or not. * * On success return for a heap tuple, *recheck_p is set to indicate whether * the quals need to be rechecked. We recheck if any of the consistent() * functions request it. recheck is not interesting when examining a non-leaf * entry, since we must visit the lower index page if there's any doubt. * Similarly, *recheck_distances_p is set to indicate whether the distances * need to be rechecked, and it is also ignored for non-leaf entries. * * If we are doing an ordered scan, so->distances[] is filled with distance * data from the distance() functions before returning success. * * We must decompress the key in the IndexTuple before passing it to the * sk_funcs (which actually are the opclass Consistent or Distance methods). * * Note that this function is always invoked in a short-lived memory context, * so we don't need to worry about cleaning up allocated memory, either here * or in the implementation of any Consistent or Distance methods. */ static bool gistindex_keytest(IndexScanDesc scan, IndexTuple tuple, Page page, OffsetNumber offset, bool *recheck_p, bool *recheck_distances_p) { GISTScanOpaque so = (GISTScanOpaque) scan->opaque; GISTSTATE *giststate = so->giststate; ScanKey key = scan->keyData; int keySize = scan->numberOfKeys; double *distance_p; Relation r = scan->indexRelation; *recheck_p = false; *recheck_distances_p = false; /* * If it's a leftover invalid tuple from pre-9.1, treat it as a match with * minimum possible distances. This means we'll always follow it to the * referenced page. */ if (GistTupleIsInvalid(tuple)) { int i; if (GistPageIsLeaf(page)) /* shouldn't happen */ elog(ERROR, "invalid GiST tuple found on leaf page"); for (i = 0; i < scan->numberOfOrderBys; i++) so->distances[i] = -get_float8_infinity(); return true; } /* Check whether it matches according to the Consistent functions */ while (keySize > 0) { Datum datum; bool isNull; datum = index_getattr(tuple, key->sk_attno, giststate->tupdesc, &isNull); if (key->sk_flags & SK_ISNULL) { /* * On non-leaf page we can't conclude that child hasn't NULL * values because of assumption in GiST: union (VAL, NULL) is VAL. * But if on non-leaf page key IS NULL, then all children are * NULL. */ if (key->sk_flags & SK_SEARCHNULL) { if (GistPageIsLeaf(page) && !isNull) return false; } else { Assert(key->sk_flags & SK_SEARCHNOTNULL); if (isNull) return false; } } else if (isNull) { return false; } else { Datum test; bool recheck; GISTENTRY de; gistdentryinit(giststate, key->sk_attno - 1, &de, datum, r, page, offset, false, isNull); /* * Call the Consistent function to evaluate the test. The * arguments are the index datum (as a GISTENTRY*), the comparison * datum, the comparison operator's strategy number and subtype * from pg_amop, and the recheck flag. * * (Presently there's no need to pass the subtype since it'll * always be zero, but might as well pass it for possible future * use.) * * We initialize the recheck flag to true (the safest assumption) * in case the Consistent function forgets to set it. */ recheck = true; test = FunctionCall5Coll(&key->sk_func, key->sk_collation, PointerGetDatum(&de), key->sk_argument, Int16GetDatum(key->sk_strategy), ObjectIdGetDatum(key->sk_subtype), PointerGetDatum(&recheck)); if (!DatumGetBool(test)) return false; *recheck_p |= recheck; } key++; keySize--; } /* OK, it passes --- now let's compute the distances */ key = scan->orderByData; distance_p = so->distances; keySize = scan->numberOfOrderBys; while (keySize > 0) { Datum datum; bool isNull; datum = index_getattr(tuple, key->sk_attno, giststate->tupdesc, &isNull); if ((key->sk_flags & SK_ISNULL) || isNull) { /* Assume distance computes as null and sorts to the end */ *distance_p = get_float8_infinity(); } else { Datum dist; bool recheck; GISTENTRY de; gistdentryinit(giststate, key->sk_attno - 1, &de, datum, r, page, offset, false, isNull); /* * Call the Distance function to evaluate the distance. The * arguments are the index datum (as a GISTENTRY*), the comparison * datum, the ordering operator's strategy number and subtype from * pg_amop, and the recheck flag. * * (Presently there's no need to pass the subtype since it'll * always be zero, but might as well pass it for possible future * use.) * * If the function sets the recheck flag, the returned distance is * a lower bound on the true distance and needs to be rechecked. * We initialize the flag to 'false'. This flag was added in * version 9.5; distance functions written before that won't know * about the flag, but are expected to never be lossy. */ recheck = false; dist = FunctionCall5Coll(&key->sk_func, key->sk_collation, PointerGetDatum(&de), key->sk_argument, Int16GetDatum(key->sk_strategy), ObjectIdGetDatum(key->sk_subtype), PointerGetDatum(&recheck)); *recheck_distances_p |= recheck; *distance_p = DatumGetFloat8(dist); } key++; distance_p++; keySize--; } return true; }
/* * GetFileSegInfo * * Get the catalog entry for an appendonly (row-oriented) relation from the * pg_aoseg_* relation that belongs to the currently used * AppendOnly table. * * If a caller intends to append to this file segment entry they must * already hold a relation Append-Only segment file (transaction-scope) lock (tag * LOCKTAG_RELATION_APPENDONLY_SEGMENT_FILE) in order to guarantee * stability of the pg_aoseg information on this segment file and exclusive right * to append data to the segment file. */ ParquetFileSegInfo * GetParquetFileSegInfo(Relation parentrel, AppendOnlyEntry *aoEntry, Snapshot parquetMetaDataSnapshot, int segno) { Relation pg_parquetseg_rel; TupleDesc pg_parquetseg_dsc; HeapTuple tuple; ScanKeyData key[1]; SysScanDesc parquetscan; Datum eof, eof_uncompressed, tupcount; bool isNull; bool indexOK; Oid indexid; ParquetFileSegInfo *fsinfo; /* * Check the pg_paqseg relation to be certain the parquet table segment file * is there. */ pg_parquetseg_rel = heap_open(aoEntry->segrelid, AccessShareLock); pg_parquetseg_dsc = RelationGetDescr(pg_parquetseg_rel); if (Gp_role == GP_ROLE_EXECUTE) { indexOK = FALSE; indexid = InvalidOid; } else { indexOK = TRUE; indexid = aoEntry->segidxid; } /* * Setup a scan key to fetch from the index by segno. */ ScanKeyInit(&key[0], (AttrNumber) Anum_pg_parquetseg_segno, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(segno)); parquetscan = systable_beginscan(pg_parquetseg_rel, indexid, indexOK, SnapshotNow, 1, &key[0]); tuple = systable_getnext(parquetscan); if (!HeapTupleIsValid(tuple)) { /* This segment file does not have an entry. */ systable_endscan(parquetscan); heap_close(pg_parquetseg_rel, AccessShareLock); return NULL ; } tuple = heap_copytuple(tuple); systable_endscan(parquetscan); Assert(HeapTupleIsValid(tuple)); fsinfo = (ParquetFileSegInfo *) palloc0(sizeof(ParquetFileSegInfo)); /* get the eof */ eof = fastgetattr(tuple, Anum_pg_parquetseg_eof, pg_parquetseg_dsc, &isNull); if (isNull) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("got invalid eof value: NULL"))); /* get the tupcount */ tupcount = fastgetattr(tuple, Anum_pg_parquetseg_tupcount, pg_parquetseg_dsc, &isNull); if (isNull) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("got invalid tupcount value: NULL"))); /* get the uncompressed eof */ eof_uncompressed = fastgetattr(tuple, Anum_pg_parquetseg_eofuncompressed, pg_parquetseg_dsc, &isNull); /* * Confusing: This eof_uncompressed variable is never used. It appears we only * call fastgetattr to get the isNull value. this variable "eof_uncompressed" is * not at all the same as fsinfo->eof_uncompressed. */ if (isNull) { /* * NULL is allowed. Tables that were created before the release of the * eof_uncompressed catalog column will have a NULL instead of a value. */ fsinfo->eof_uncompressed = InvalidUncompressedEof; } else { fsinfo->eof_uncompressed = (int64) DatumGetFloat8(eof_uncompressed); } fsinfo->segno = segno; fsinfo->eof = (int64) DatumGetFloat8(eof); fsinfo->tupcount = (int64) DatumGetFloat8(tupcount); ItemPointerSetInvalid(&fsinfo->sequence_tid); if (fsinfo->eof < 0) ereport(ERROR, (errcode(ERRCODE_GP_INTERNAL_ERROR), errmsg("invalid eof " INT64_FORMAT " for relation %s", fsinfo->eof, RelationGetRelationName(parentrel)))); /* Finish up scan and close appendonly catalog. */ heap_close(pg_parquetseg_rel, AccessShareLock); return fsinfo; }
void ParquetColumnReader_readPOLYGON( ParquetColumnReader readers[], Datum *value, bool *null) { POLYGON *polygon; Datum child_values[6] = {0}; /* boundbox:{x1,y1,x2,y2}, points:{x,y} */ bool child_nulls[6] = {0}; int npts, maxnpts; /* * read BOX boundbox */ ParquetColumnReader_readValue(&readers[0], &child_values[0], &child_nulls[0], HAWQ_TYPE_FLOAT8); ParquetColumnReader_readValue(&readers[1], &child_values[1], &child_nulls[1], HAWQ_TYPE_FLOAT8); ParquetColumnReader_readValue(&readers[2], &child_values[2], &child_nulls[2], HAWQ_TYPE_FLOAT8); ParquetColumnReader_readValue(&readers[3], &child_values[3], &child_nulls[3], HAWQ_TYPE_FLOAT8); Insist(child_nulls[0] == child_nulls[1] && child_nulls[2] == child_nulls[3] && child_nulls[0] == child_nulls[2]); if (child_nulls[0]) { ParquetColumnReader_readValue(&readers[4], &child_values[4], &child_nulls[4], HAWQ_TYPE_FLOAT8); ParquetColumnReader_readValue(&readers[5], &child_values[5], &child_nulls[5], HAWQ_TYPE_FLOAT8); Insist(child_nulls[4] && child_nulls[5]); *null = true; return; } npts = 0; polygon = readers[0].geoval; if (polygon == NULL) { maxnpts = 10; polygon = palloc(get_polygon_size(maxnpts)); } else { maxnpts = polygon->npts; } polygon->boundbox.high.x = DatumGetFloat8(child_values[0]); polygon->boundbox.high.y = DatumGetFloat8(child_values[1]); polygon->boundbox.low.x = DatumGetFloat8(child_values[2]); polygon->boundbox.low.y = DatumGetFloat8(child_values[3]); /* * read repeated points */ while (true) { if (npts >= maxnpts) { maxnpts *= 2; polygon = repalloc(polygon, get_polygon_size(maxnpts)); } ParquetColumnReader_readValue(&readers[4], &child_values[4], &child_nulls[4], HAWQ_TYPE_FLOAT8); ParquetColumnReader_readValue(&readers[5], &child_values[5], &child_nulls[5], HAWQ_TYPE_FLOAT8); polygon->p[npts].x = DatumGetFloat8(child_values[4]); polygon->p[npts].y = DatumGetFloat8(child_values[5]); npts++; if (NextRepetitionLevel(&readers[4]) == 0) break; /* no more points in this polygon */ } polygon = repalloc(polygon, get_polygon_size(npts)); SET_VARSIZE(polygon, get_polygon_size(npts)); polygon->npts = npts; *value = PointerGetDatum(polygon); *null = false; readers[0].geoval = polygon; }
Datum spg_kd_inner_consistent(PG_FUNCTION_ARGS) { spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0); spgInnerConsistentOut *out = (spgInnerConsistentOut *) PG_GETARG_POINTER(1); double coord; int which; int i; Assert(in->hasPrefix); coord = DatumGetFloat8(in->prefixDatum); if (in->allTheSame) elog(ERROR, "allTheSame should not occur for k-d trees"); Assert(in->nNodes == 2); /* "which" is a bitmask of children that satisfy all constraints */ which = (1 << 1) | (1 << 2); for (i = 0; i < in->nkeys; i++) { Point *query = DatumGetPointP(in->scankeys[i].sk_argument); BOX *boxQuery; switch (in->scankeys[i].sk_strategy) { case RTLeftStrategyNumber: if ((in->level % 2) != 0 && FPlt(query->x, coord)) which &= (1 << 1); break; case RTRightStrategyNumber: if ((in->level % 2) != 0 && FPgt(query->x, coord)) which &= (1 << 2); break; case RTSameStrategyNumber: if ((in->level % 2) != 0) { if (FPlt(query->x, coord)) which &= (1 << 1); else if (FPgt(query->x, coord)) which &= (1 << 2); } else { if (FPlt(query->y, coord)) which &= (1 << 1); else if (FPgt(query->y, coord)) which &= (1 << 2); } break; case RTBelowStrategyNumber: if ((in->level % 2) == 0 && FPlt(query->y, coord)) which &= (1 << 1); break; case RTAboveStrategyNumber: if ((in->level % 2) == 0 && FPgt(query->y, coord)) which &= (1 << 2); break; case RTContainedByStrategyNumber: /* * For this operator, the query is a box not a point. We * cheat to the extent of assuming that DatumGetPointP won't * do anything that would be bad for a pointer-to-box. */ boxQuery = DatumGetBoxP(in->scankeys[i].sk_argument); if ((in->level % 2) != 0) { if (FPlt(boxQuery->high.x, coord)) which &= (1 << 1); else if (FPgt(boxQuery->low.x, coord)) which &= (1 << 2); } else { if (FPlt(boxQuery->high.y, coord)) which &= (1 << 1); else if (FPgt(boxQuery->low.y, coord)) which &= (1 << 2); } break; default: elog(ERROR, "unrecognized strategy number: %d", in->scankeys[i].sk_strategy); break; } if (which == 0) break; /* no need to consider remaining conditions */ } /* We must descend into the children identified by which */ out->nodeNumbers = (int *) palloc(sizeof(int) * 2); out->nNodes = 0; for (i = 1; i <= 2; i++) { if (which & (1 << i)) out->nodeNumbers[out->nNodes++] = i - 1; } /* Set up level increments, too */ out->levelAdds = (int *) palloc(sizeof(int) * 2); out->levelAdds[0] = 1; out->levelAdds[1] = 1; PG_RETURN_VOID(); }
/* * Calculate the average of function P(x), in the interval [length1, length2], * where P(x) is the fraction of tuples with length < x (or length <= x if * 'equal' is true). */ static double calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues, double length1, double length2, bool equal) { double frac; double A, B, PA, PB; double pos; int i; double area; Assert(length2 >= length1); if (length2 < 0.0) return 0.0; /* shouldn't happen, but doesn't hurt to check */ /* All lengths in the table are <= infinite. */ if (is_infinite(length2) && equal) return 1.0; /*---------- * The average of a function between A and B can be calculated by the * formula: * * B * 1 / * ------- | P(x)dx * B - A / * A * * The geometrical interpretation of the integral is the area under the * graph of P(x). P(x) is defined by the length histogram. We calculate * the area in a piecewise fashion, iterating through the length histogram * bins. Each bin is a trapezoid: * * P(x2) * /| * / | * P(x1)/ | * | | * | | * ---+---+-- * x1 x2 * * where x1 and x2 are the boundaries of the current histogram, and P(x1) * and P(x1) are the cumulative fraction of tuples at the boundaries. * * The area of each trapezoid is 1/2 * (P(x2) + P(x1)) * (x2 - x1) * * The first bin contains the lower bound passed by the caller, so we * use linear interpolation between the previous and next histogram bin * boundary to calculate P(x1). Likewise for the last bin: we use linear * interpolation to calculate P(x2). For the bins in between, x1 and x2 * lie on histogram bin boundaries, so P(x1) and P(x2) are simply: * P(x1) = (bin index) / (number of bins) * P(x2) = (bin index + 1 / (number of bins) */ /* First bin, the one that contains lower bound */ i = length_hist_bsearch(length_hist_values, length_hist_nvalues, length1, equal); if (i >= length_hist_nvalues - 1) return 1.0; if (i < 0) { i = 0; pos = 0.0; } else { /* interpolate length1's position in the bin */ pos = get_len_position(length1, DatumGetFloat8(length_hist_values[i]), DatumGetFloat8(length_hist_values[i + 1])); } PB = (((double) i) + pos) / (double) (length_hist_nvalues - 1); B = length1; /* * In the degenerate case that length1 == length2, simply return * P(length1). This is not merely an optimization: if length1 == length2, * we'd divide by zero later on. */ if (length2 == length1) return PB; /* * Loop through all the bins, until we hit the last bin, the one that * contains the upper bound. (if lower and upper bounds are in the same * bin, this falls out immediately) */ area = 0.0; for (; i < length_hist_nvalues - 1; i++) { double bin_upper = DatumGetFloat8(length_hist_values[i + 1]); /* check if we've reached the last bin */ if (!(bin_upper < length2 || (equal && bin_upper <= length2))) break; /* the upper bound of previous bin is the lower bound of this bin */ A = B; PA = PB; B = bin_upper; PB = (double) i / (double) (length_hist_nvalues - 1); /* * Add the area of this trapezoid to the total. The point of the * if-check is to avoid NaN, in the corner case that PA == PB == 0, * and B - A == Inf. The area of a zero-height trapezoid (PA == PB == * 0) is zero, regardless of the width (B - A). */ if (PA > 0 || PB > 0) area += 0.5 * (PB + PA) * (B - A); } /* Last bin */ A = B; PA = PB; B = length2; /* last bin ends at the query upper bound */ if (i >= length_hist_nvalues - 1) pos = 0.0; else { if (DatumGetFloat8(length_hist_values[i]) == DatumGetFloat8(length_hist_values[i + 1])) pos = 0.0; else pos = get_len_position(length2, DatumGetFloat8(length_hist_values[i]), DatumGetFloat8(length_hist_values[i + 1])); } PB = (((double) i) + pos) / (double) (length_hist_nvalues - 1); if (PA > 0 || PB > 0) area += 0.5 * (PB + PA) * (B - A); /* * Ok, we have calculated the area, ie. the integral. Divide by width to * get the requested average. * * Avoid NaN arising from infinite / infinite. This happens at least if * length2 is infinite. It's not clear what the correct value would be in * that case, so 0.5 seems as good as any value. */ if (is_infinite(area) && is_infinite(length2)) frac = 0.5; else frac = area / (length2 - length1); return frac; }
Datum alpine_miner_nn_ca_o(PG_FUNCTION_ARGS) { ArrayType *weight_arg, *columns_arg, *input_range_arg, *input_base_arg,*hidden_node_number_arg, *result; Datum *weight_data, *columns_data, *input_range_data, *input_base_data, *hidden_node_number_data, *result_data; bool *weight_nulls, *columns_nulls, *input_range_nulls, *input_base_nulls, *hidden_node_number_nulls,*result_nulls; int weight_count, columns_count, input_range_count, input_base_count, hidden_node_number_count,result_count ; Oid result_eltype; int16 result_typlen; bool result_typbyval; char result_typalign; double output_range_arg,output_base_arg; int hidden_layer_number_arg, output_node_no_arg; bool normalize_arg, numerical_label_arg ; int ndims, *dims, *lbs; int i; int j; int k; int all_hidden_node_count; int weight_index; int hidden_node_number_index = 0; bool null_data; double * input; double * output; int * hidden_node_number; double *weight; double *hidden_node_output; if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3) || PG_ARGISNULL(4) || PG_ARGISNULL(5) || PG_ARGISNULL(6) || PG_ARGISNULL(7) || PG_ARGISNULL(8) || PG_ARGISNULL(9) || PG_ARGISNULL(10)) { PG_RETURN_NULL(); } /* get weight_arg args */ weight_arg = PG_GETARG_ARRAYTYPE_P(0); null_data = alpine_miner_deconstruct_array(weight_arg, &weight_data, &weight_nulls,&weight_count); if (null_data) { PG_RETURN_NULL(); } columns_arg = PG_GETARG_ARRAYTYPE_P(1); null_data = alpine_miner_deconstruct_array(columns_arg, &columns_data, &columns_nulls,&columns_count); if (null_data) { PG_RETURN_NULL(); } /* get input_range_arg args */ input_range_arg = PG_GETARG_ARRAYTYPE_P(2); null_data = alpine_miner_deconstruct_array(input_range_arg, &input_range_data, &input_range_nulls,&input_range_count); if (null_data) { PG_RETURN_NULL(); } /* get input_base_arg args */ input_base_arg = PG_GETARG_ARRAYTYPE_P(3); null_data = alpine_miner_deconstruct_array(input_base_arg, &input_base_data, &input_base_nulls,&input_base_count); if (null_data) { PG_RETURN_NULL(); } /* get hidden_node_number_arg args */ hidden_node_number_arg = PG_GETARG_ARRAYTYPE_P(4); null_data = alpine_miner_deconstruct_array(hidden_node_number_arg, &hidden_node_number_data, &hidden_node_number_nulls,&hidden_node_number_count); if (null_data) { PG_RETURN_NULL(); } hidden_layer_number_arg= PG_GETARG_INT32(5); output_range_arg = PG_GETARG_FLOAT8(6); output_base_arg = PG_GETARG_FLOAT8(7); output_node_no_arg = PG_GETARG_INT32(8); normalize_arg = PG_GETARG_BOOL(9); numerical_label_arg = PG_GETARG_BOOL(10); #ifdef ALPINE_DEBUG elog(WARNING,"%f",DatumGetFloat8(columns_data[0])); #endif input = (double*)palloc(columns_count * sizeof(double));; output = (double*)palloc(output_node_no_arg * sizeof(double)); hidden_node_number = (int*) palloc(hidden_node_number_count * sizeof(int)); weight = (double*)palloc(weight_count * sizeof(double)); for (i = 0; i < weight_count; i++) { weight[i] = DatumGetFloat8(weight_data[i]); } all_hidden_node_count = 0; for (i = 0; i < hidden_layer_number_arg; i++) { hidden_node_number[i] = DatumGetInt32(hidden_node_number_data[i]); all_hidden_node_count += hidden_node_number[i]; } hidden_node_output = (double*)palloc(all_hidden_node_count * sizeof(double)); /* get output array element type */ result_eltype = FLOAT8OID; get_typlenbyvalalign(result_eltype, &result_typlen, &result_typbyval, &result_typalign); /* construct result array */ result_count = output_node_no_arg; result_data = (Datum *)palloc(result_count * sizeof(Datum)); result_nulls = (bool *)palloc(result_count * sizeof(bool)); for (i = 0; i < result_count; i++) { result_nulls[i] = false; } //caculate input if (normalize_arg) { i = 0; while (i < columns_count) { if (DatumGetFloat8(input_range_data[i]) != 0) { input[i] = ((DatumGetFloat8(columns_data[i])-DatumGetFloat8(input_base_data[i]))/DatumGetFloat8(input_range_data[i])); } else { input[i] = (DatumGetFloat8(columns_data[i])-DatumGetFloat8(input_base_data[i])); } #ifdef ALPINE_DEBUG elog(WARNING, "input:%f", input[i]); #endif i = i + 1; } } else { i = 0; while (i < columns_count) { input[i] = DatumGetFloat8(columns_data[i]); i = i + 1; } } // caculate hidden node output of 1st layer i = 0; while (i < hidden_node_number[0]) { hidden_node_output[i] = weight[0+i*(columns_count + 1)]; j = 0; while (j < columns_count) { hidden_node_output[i] = hidden_node_output[i]+input[j]*weight[1 + j + i *(columns_count + 1)]; #ifdef ALPINE_DEBUG elog(WARNING,"hiddensum[%d] input[%d] %f weight[%d] %f", i, j,input[j] , 1+j +(i)*(columns_count +1), weight[1+j +i*(columns_count + 1)]); #endif j = j + 1; } if (hidden_node_output[i] < -45.0) { hidden_node_output[i] = 0; } else if (hidden_node_output[i] > 45.0) { hidden_node_output[i] = 1; } else { hidden_node_output[i] = (1.0/(1.0+exp( -1.0 * hidden_node_output[i]))); } #ifdef ALPINE_DEBUG elog(WARNING,"hidden[%d] %f", i, hidden_node_output[i]); #endif i = i + 1; } // calculate hidden layer 2~last output weight_index = hidden_node_number[0] * (columns_count + 1) ; if (hidden_layer_number_arg > 1) { hidden_node_number_index = 0; i = 1; while (i < hidden_layer_number_arg ) { hidden_node_number_index = hidden_node_number_index + hidden_node_number[i - 1]; j = 0; while (j < hidden_node_number[i]) { hidden_node_output[hidden_node_number_index + j] = weight[weight_index + (hidden_node_number[i - 1] +1) * j]; k = 0; while (k < hidden_node_number[i - 1]) { hidden_node_output[hidden_node_number_index + j] = hidden_node_output[hidden_node_number_index + j]+hidden_node_output[hidden_node_number_index - hidden_node_number[i - 1] + k]*weight[weight_index + (hidden_node_number[i - 1] +1) * j + k + 1]; k = k + 1; } if (hidden_node_output[hidden_node_number_index + j] < -45.0) { hidden_node_output[hidden_node_number_index + j] = 0; } else if (hidden_node_output[hidden_node_number_index + j] > 45.0) { hidden_node_output[hidden_node_number_index + j] = 1; } else { hidden_node_output[hidden_node_number_index + j] = (1.0/(1+exp(-1.0*hidden_node_output[hidden_node_number_index+j]))); } j = j + 1; } weight_index = weight_index + hidden_node_number[i] * (hidden_node_number[i - 1] + 1); i = i + 1; } } //compute output value of output node; i = 0; while (i < output_node_no_arg) { output[i] = weight[weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i]; #ifdef ALPINE_DEBUG elog(WARNING,"weightindex:%d,weight[%d] %f",weight_index, weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i, output[i]); #endif j = 0; while (j < hidden_node_number[hidden_layer_number_arg-1]) { #ifdef ALPINE_DEBUG elog(WARNING,"ouput[%d]:%f ,hidden_node_number_index:%d,j:%d, weight[%d]:%f",i,output[i], hidden_node_number_index ,j,1+j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i , weight[1 + j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i ]); #endif output[i] = output[i]+hidden_node_output[hidden_node_number_index + j] * weight[1 + j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i ]; j = j + 1; } #ifdef ALPINE_DEBUG elog(WARNING,"ouputsum[%d] %f", i, output[i]); #endif if (numerical_label_arg) { output[i] = ((output[i]) * output_range_arg+output_base_arg); #ifdef ALPINE_DEBUG elog(WARNING,"output:%f, %f,%f",output[i],output_range_arg,output_base_arg); #endif } else { if (output[i] < -45.0) { output[i] = 0; } else if (output[i] > 45.0) { output[i] = 1; } else { output[i] = (1.0/(1+exp(-1.0*output[i]))); } } #ifdef ALPINE_DEBUG elog(WARNING,"ouputsum2[%d] %f", i, output[i]); #endif i = i + 1; } ndims = 1; dims = (int *) palloc(sizeof(int)); dims[0] = result_count; lbs = (int *) palloc(sizeof(int)); lbs[0] = 1; for (i = 0; i < output_node_no_arg; i++) { result_data[i] = Float8GetDatum(output[i]); #ifdef ALPINE_DEBUG elog(WARNING,"output[%d]:%f",i, output[i]); #endif } result = construct_md_array((void *)result_data, result_nulls, ndims, dims, lbs, result_eltype, result_typlen, result_typbyval, result_typalign); // pfree(result); pfree(weight_data); pfree(columns_data); pfree(input_range_data); pfree(input_base_data); pfree(hidden_node_number_data); pfree(result_data); pfree(weight_nulls); pfree(columns_nulls); pfree(input_range_nulls); pfree(input_base_nulls); pfree(hidden_node_number_nulls); pfree(result_nulls); pfree(input); pfree(output); pfree(lbs); pfree(dims); pfree(hidden_node_output); pfree(weight); pfree(hidden_node_number); PG_RETURN_ARRAYTYPE_P(result); }
/* * gistindex_keytest() -- does this index tuple satisfy the scan key(s)? * * The index tuple might represent either a heap tuple or a lower index page, * depending on whether the containing page is a leaf page or not. * * On success return for a heap tuple, *recheck_p is set to indicate * whether recheck is needed. We recheck if any of the consistent() functions * request it. recheck is not interesting when examining a non-leaf entry, * since we must visit the lower index page if there's any doubt. * * If we are doing an ordered scan, so->distances[] is filled with distance * data from the distance() functions before returning success. * * We must decompress the key in the IndexTuple before passing it to the * sk_funcs (which actually are the opclass Consistent or Distance methods). * * Note that this function is always invoked in a short-lived memory context, * so we don't need to worry about cleaning up allocated memory, either here * or in the implementation of any Consistent or Distance methods. */ static bool gistindex_keytest(IndexScanDesc scan, IndexTuple tuple, Page page, OffsetNumber offset, bool *recheck_p) { GISTScanOpaque so = (GISTScanOpaque) scan->opaque; GISTSTATE *giststate = so->giststate; ScanKey key = scan->keyData; int keySize = scan->numberOfKeys; double *distance_p; Relation r = scan->indexRelation; *recheck_p = false; /* * If it's a leftover invalid tuple from pre-9.1, treat it as a match with * minimum possible distances. This means we'll always follow it to the * referenced page. * * GPDB: the virtual TIDs created for AO tables use the full range of * offset numbers from 0 to 65535. So a tuple on leaf page that looks like * an invalid tuple, is actually ok. */ if (!GistPageIsLeaf(page) && GistTupleIsInvalid(tuple)) { int i; for (i = 0; i < scan->numberOfOrderBys; i++) so->distances[i] = -get_float8_infinity(); return true; } /* Check whether it matches according to the Consistent functions */ while (keySize > 0) { Datum datum; bool isNull; datum = index_getattr(tuple, key->sk_attno, giststate->tupdesc, &isNull); if (key->sk_flags & SK_ISNULL) { /* * On non-leaf page we can't conclude that child hasn't NULL * values because of assumption in GiST: union (VAL, NULL) is VAL. * But if on non-leaf page key IS NULL, then all children are * NULL. */ if (key->sk_flags & SK_SEARCHNULL) { if (GistPageIsLeaf(page) && !isNull) return false; } else { Assert(key->sk_flags & SK_SEARCHNOTNULL); if (isNull) return false; } } else if (isNull) { return false; } else { Datum test; bool recheck; GISTENTRY de; gistdentryinit(giststate, key->sk_attno - 1, &de, datum, r, page, offset, FALSE, isNull); /* * Call the Consistent function to evaluate the test. The * arguments are the index datum (as a GISTENTRY*), the comparison * datum, the comparison operator's strategy number and subtype * from pg_amop, and the recheck flag. * * (Presently there's no need to pass the subtype since it'll * always be zero, but might as well pass it for possible future * use.) * * We initialize the recheck flag to true (the safest assumption) * in case the Consistent function forgets to set it. */ recheck = true; test = FunctionCall5Coll(&key->sk_func, key->sk_collation, PointerGetDatum(&de), key->sk_argument, Int32GetDatum(key->sk_strategy), ObjectIdGetDatum(key->sk_subtype), PointerGetDatum(&recheck)); if (!DatumGetBool(test)) return false; *recheck_p |= recheck; } key++; keySize--; } /* OK, it passes --- now let's compute the distances */ key = scan->orderByData; distance_p = so->distances; keySize = scan->numberOfOrderBys; while (keySize > 0) { Datum datum; bool isNull; datum = index_getattr(tuple, key->sk_attno, giststate->tupdesc, &isNull); if ((key->sk_flags & SK_ISNULL) || isNull) { /* Assume distance computes as null and sorts to the end */ *distance_p = get_float8_infinity(); } else { Datum dist; GISTENTRY de; gistdentryinit(giststate, key->sk_attno - 1, &de, datum, r, page, offset, FALSE, isNull); /* * Call the Distance function to evaluate the distance. The * arguments are the index datum (as a GISTENTRY*), the comparison * datum, and the ordering operator's strategy number and subtype * from pg_amop. * * (Presently there's no need to pass the subtype since it'll * always be zero, but might as well pass it for possible future * use.) * * Note that Distance functions don't get a recheck argument. We * can't tolerate lossy distance calculations on leaf tuples; * there is no opportunity to re-sort the tuples afterwards. */ dist = FunctionCall4Coll(&key->sk_func, key->sk_collation, PointerGetDatum(&de), key->sk_argument, Int32GetDatum(key->sk_strategy), ObjectIdGetDatum(key->sk_subtype)); *distance_p = DatumGetFloat8(dist); } key++; distance_p++; keySize--; } return true; }
Datum alpine_miner_nn_ca_change(PG_FUNCTION_ARGS) { ArrayType *weight_arg, *columns_arg, *input_range_arg, *input_base_arg,*hidden_node_number_arg, *result; Datum *weight_data, *columns_data, *input_range_data, *input_base_data, *hidden_node_number_data, *result_data; bool *weight_nulls, *columns_nulls, *input_range_nulls, *input_base_nulls, *hidden_node_number_nulls,*result_nulls; int weight_count, columns_count, input_range_count, input_base_count, hidden_node_number_count,result_count ; Oid result_eltype; int16 result_typlen; bool result_typbyval; char result_typalign; double output_range_arg,output_base_arg, learning_rate_ar, label_arg; int hidden_layer_number_arg, output_node_no_arg, set_size_arg; bool normalize_arg, numerical_label_arg ; int ndims, *dims, *lbs; int i; int j; int k; int all_hidden_node_count; int weight_index; int hidden_node_number_index = 0; bool null_data; double * input; double * output; int * hidden_node_number; double *weight; double *hidden_node_output; double delta = 0.0; double total_error = 0.0; double * output_error; double direct_output_error = 0.0; double * hidden_node_error; double error_sum = 0.0; double current_change = 0.0; double threshold_change = 0.0; if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3) || PG_ARGISNULL(4) || PG_ARGISNULL(5) || PG_ARGISNULL(6) || PG_ARGISNULL(7) || PG_ARGISNULL(8) || PG_ARGISNULL(9) || PG_ARGISNULL(10) || PG_ARGISNULL(11) || PG_ARGISNULL(12)){ PG_RETURN_NULL(); } /* get weight_arg args */ weight_arg = PG_GETARG_ARRAYTYPE_P(0); null_data = alpine_miner_deconstruct_array(weight_arg, &weight_data, &weight_nulls,&weight_count); if (null_data) { PG_RETURN_NULL(); } columns_arg = PG_GETARG_ARRAYTYPE_P(1); null_data = alpine_miner_deconstruct_array(columns_arg, &columns_data, &columns_nulls,&columns_count); if (null_data) { PG_RETURN_NULL(); } /* get input_range_arg args */ input_range_arg = PG_GETARG_ARRAYTYPE_P(2); null_data = alpine_miner_deconstruct_array(input_range_arg, &input_range_data, &input_range_nulls,&input_range_count); if (null_data) { PG_RETURN_NULL(); } /* get input_base_arg args */ input_base_arg = PG_GETARG_ARRAYTYPE_P(3); null_data = alpine_miner_deconstruct_array(input_base_arg, &input_base_data, &input_base_nulls,&input_base_count); if (null_data) { PG_RETURN_NULL(); } /* get hidden_node_number_arg args */ hidden_node_number_arg = PG_GETARG_ARRAYTYPE_P(4); null_data = alpine_miner_deconstruct_array(hidden_node_number_arg, &hidden_node_number_data, &hidden_node_number_nulls,&hidden_node_number_count); if (null_data) { PG_RETURN_NULL(); } hidden_layer_number_arg= PG_GETARG_INT32(5); output_range_arg = PG_GETARG_FLOAT8(6); output_base_arg = PG_GETARG_FLOAT8(7); output_node_no_arg = PG_GETARG_INT32(8); normalize_arg = PG_GETARG_BOOL(9); numerical_label_arg = PG_GETARG_BOOL(10); label_arg = PG_GETARG_FLOAT8(11); set_size_arg = PG_GETARG_INT32(12); if (set_size_arg <= 0) { set_size_arg = 1; } #ifdef ALPINE_DEBUG elog(WARNING,"%f",DatumGetFloat8(columns_data[0])); #endif input = (double*)palloc(columns_count * sizeof(double));; output = (double*)palloc(output_node_no_arg * sizeof(double)); hidden_node_number = (int*) palloc(hidden_node_number_count * sizeof(int)); weight = (double*)palloc(weight_count * sizeof(double)); for (i = 0; i < weight_count; i++) { weight[i] = DatumGetFloat8(weight_data[i]); } all_hidden_node_count = 0; for (i = 0; i < hidden_layer_number_arg; i++) { hidden_node_number[i] = DatumGetInt32(hidden_node_number_data[i]); all_hidden_node_count += hidden_node_number[i]; } hidden_node_output = (double*)palloc(all_hidden_node_count * sizeof(double)); //caculate input if (normalize_arg) { i = 0; while (i < columns_count) { if (DatumGetFloat8(input_range_data[i]) != 0) { input[i] = ((DatumGetFloat8(columns_data[i])-DatumGetFloat8(input_base_data[i]))/DatumGetFloat8(input_range_data[i])); } else { input[i] = (DatumGetFloat8(columns_data[i])-DatumGetFloat8(input_base_data[i])); } #ifdef ALPINE_DEBUG elog(WARNING, "input:%f", input[i]); #endif i = i + 1; } } else { i = 0; while (i < columns_count) { input[i] = DatumGetFloat8(columns_data[i]); i = i + 1; } } // caculate hidden node output of 1st layer i = 0; while (i < hidden_node_number[0]) { hidden_node_output[i] = weight[0+i*(columns_count + 1)]; j = 0; while (j < columns_count) { hidden_node_output[i] = hidden_node_output[i]+input[j]*weight[1 + j + i *(columns_count + 1)]; #ifdef ALPINE_DEBUG elog(WARNING,"hiddensum[%d] input[%d] %f weight[%d] %f", i, j,input[j] , 1+j +(i)*(columns_count +1), weight[1+j +i*(columns_count + 1)]); #endif j = j + 1; } if (hidden_node_output[i] < -45.0) { hidden_node_output[i] = 0; } else if (hidden_node_output[i] > 45.0) { hidden_node_output[i] = 1; } else { hidden_node_output[i] = (1.0/(1.0+exp( -1.0 * hidden_node_output[i]))); } #ifdef ALPINE_DEBUG elog(WARNING,"hidden[%d] %f", i, hidden_node_output[i]); #endif i = i + 1; } // calculate hidden layer 2~last output weight_index = hidden_node_number[0] * (columns_count + 1) ; if (hidden_layer_number_arg > 1) { hidden_node_number_index = 0; i = 1; while (i < hidden_layer_number_arg ) { hidden_node_number_index = hidden_node_number_index + hidden_node_number[i - 1]; j = 0; while (j < hidden_node_number[i]) { hidden_node_output[hidden_node_number_index + j] = weight[weight_index + (hidden_node_number[i - 1] +1) * j]; k = 0; while (k < hidden_node_number[i - 1]) { hidden_node_output[hidden_node_number_index + j] = hidden_node_output[hidden_node_number_index + j]+hidden_node_output[hidden_node_number_index - hidden_node_number[i - 1] + k]*weight[weight_index + (hidden_node_number[i - 1] +1) * j + k + 1]; k = k + 1; } if (hidden_node_output[hidden_node_number_index + j] < -45.0) { hidden_node_output[hidden_node_number_index + j] = 0; } else if (hidden_node_output[hidden_node_number_index + j] > 45.0) { hidden_node_output[hidden_node_number_index + j] = 1; } else { hidden_node_output[hidden_node_number_index + j] = (1.0/(1+exp(-1.0*hidden_node_output[hidden_node_number_index+j]))); } j = j + 1; } weight_index = weight_index + hidden_node_number[i] * (hidden_node_number[i - 1] + 1); i = i + 1; } } //compute output value of output node; i = 0; while (i < output_node_no_arg) { output[i] = weight[weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i]; #ifdef ALPINE_DEBUG elog(WARNING,"weightindex:%d,weight[%d] %f",weight_index, weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i, output[i]); #endif j = 0; while (j < hidden_node_number[hidden_layer_number_arg-1]) { #ifdef ALPINE_DEBUG elog(WARNING,"ouput[%d]:%f ,hidden_node_number_index:%d,j:%d, weight[%d]:%f",i,output[i], hidden_node_number_index ,j,1+j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i , weight[1 + j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i ]); #endif output[i] = output[i]+hidden_node_output[hidden_node_number_index + j] * weight[1 + j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i ]; j = j + 1; } #ifdef ALPINE_DEBUG elog(WARNING,"ouputsum[%d] %f", i, output[i]); #endif if (numerical_label_arg) { output[i] = ((output[i]) * output_range_arg+output_base_arg); #ifdef ALPINE_DEBUG elog(WARNING,"output:%f, %f,%f",output[i],output_range_arg,output_base_arg); #endif } else { if (output[i] < -45.0) { output[i] = 0; } else if (output[i] > 45.0) { output[i] = 1; } else { output[i] = (1.0/(1+exp(-1.0*output[i]))); } } #ifdef ALPINE_DEBUG elog(WARNING,"ouputsum2[%d] %f", i, output[i]); #endif i = i + 1; } /* get output array element type */ result_eltype = FLOAT8OID; get_typlenbyvalalign(result_eltype, &result_typlen, &result_typbyval, &result_typalign); /* construct result array */ result_count = weight_count + 1; result_data = (Datum *)palloc(result_count * sizeof(Datum)); result_nulls = (bool *)palloc(result_count * sizeof(bool)); for (i = 0; i < result_count; i++) { result_nulls[i] = false; } //compute error of output node output_error = (double *)palloc(output_node_no_arg * sizeof(double)); for(i = 0; i < output_node_no_arg; i++) { if(numerical_label_arg) { if (output_range_arg == 0.0) { direct_output_error = 0.0; } else { direct_output_error = (label_arg - output[i])/output_range_arg; } output_error[i] = direct_output_error; } else { if (((int)label_arg) == i) { direct_output_error = 1.0 - output[i]; } else { direct_output_error = 0.0 - output[i]; } #ifdef ALPINE_DEBUG elog(WARNING,"label_arg :%f %d %d", label_arg, i, (((int)label_arg) == i)); #endif output_error[i] = direct_output_error * output[i] * (1- output[i]); } total_error += direct_output_error*direct_output_error; #ifdef ALPINE_DEBUG elog(WARNING,"output_error[%d] %f totalerror:%f", i, output_error[i], total_error); #endif } //compute hidden_node_error of last layer hidden_node---- hidden_node_error = (double*)palloc(all_hidden_node_count * sizeof(double)); weight_index = weight_count - output_node_no_arg*(hidden_node_number[hidden_layer_number_arg - 1] + 1) ; hidden_node_number_index = all_hidden_node_count - hidden_node_number[hidden_layer_number_arg - 1]; for(i = 0; i < hidden_node_number[hidden_layer_number_arg - 1]; i++) { error_sum = 0.0; for(k = 0; k < output_node_no_arg; k++) { error_sum = error_sum+output_error[k]*weight[weight_index + (hidden_node_number[hidden_layer_number_arg - 1] + 1)*k + i + 1]; #ifdef ALPINE_DEBUG elog(WARNING,"output_error[%d]:%f,weight[%d]:%f",k,output_error[k],weight_index + (hidden_node_number[hidden_layer_number_arg - 1] + 1)*k + i + 1, weight[weight_index + (hidden_node_number[hidden_layer_number_arg - 1] + 1)*k + i + 1]); #endif } hidden_node_error[hidden_node_number_index + i] = error_sum*hidden_node_output[hidden_node_number_index + i]*(1.0-hidden_node_output[hidden_node_number_index + i]); #ifdef ALPINE_DEBUG elog(WARNING,"hidden_node_error[%d] %f ", hidden_node_number_index+i, hidden_node_error[hidden_node_number_index + i]); #endif } //compute hidden_node_error of 1 layer to the one before last layer hidden node if (hidden_layer_number_arg > 1) { weight_index = weight_index - (hidden_node_number[hidden_layer_number_arg - 2] + 1)*hidden_node_number[hidden_layer_number_arg - 1]; hidden_node_number_index = hidden_node_number_index - hidden_node_number[hidden_layer_number_arg - 2]; for(i = hidden_layer_number_arg - 2; i >= 0; i--) { for(j = 0; j < hidden_node_number[i]; j++) { error_sum = 0.0; for (k = 0; k < hidden_node_number[i + 1]; k++) { error_sum = error_sum+hidden_node_error[hidden_node_number_index + hidden_node_number[i] + k]*weight[weight_index + (hidden_node_number[i]+1)*(k) + j + 1]; #ifdef ALPINE_DEBUG elog(WARNING,"i:%d j:%d k:%d; hidden_node_error[%d]:%f,weight[%d]:%f",i,j,k,hidden_node_number_index + hidden_node_number[i] + k, hidden_node_error[hidden_node_number_index + hidden_node_number[i] + k], weight_index + (hidden_node_number[i]+1)*(k) + j + 1,weight[weight_index + (hidden_node_number[i]+1)*(k) + j + 1]); #endif } hidden_node_error[hidden_node_number_index + j] = error_sum*hidden_node_output[hidden_node_number_index + j]*(1-hidden_node_output[hidden_node_number_index + j]); #ifdef ALPINE_DEBUG elog(WARNING,"hidden_node_error[%d] %f ", hidden_node_number_index+j, hidden_node_error[hidden_node_number_index + j]); #endif } weight_index = weight_index - (hidden_node_number[i - 1]+1) * hidden_node_number[i]; hidden_node_number_index = hidden_node_number_index - hidden_node_number[i - 1]; } } //compute weight change of output node weight_index = weight_count - (hidden_node_number[hidden_layer_number_arg - 1]+ 1)* output_node_no_arg; hidden_node_number_index = all_hidden_node_count - hidden_node_number[hidden_layer_number_arg - 1]; for(i = 0; i < output_node_no_arg; i++) { delta = 1.0/set_size_arg*output_error[i]; threshold_change = delta; result_data[weight_index +(hidden_node_number[hidden_layer_number_arg - 1]+ 1)*(i)] = Float8GetDatum(threshold_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f ", weight_index +(hidden_node_number[hidden_layer_number_arg - 1]+ 1)*(i), threshold_change); #endif for(j = 0; j < hidden_node_number[hidden_layer_number_arg - 1] ; j++) { current_change = delta * hidden_node_output[hidden_node_number_index + j]; result_data[weight_index +(hidden_node_number[hidden_layer_number_arg - 1]+ 1)*(i) + 1 +j] = Float8GetDatum(current_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f , i:%d j:%d output_error[%d]:%f, hidden_node_output[%d]:%f", weight_index +(hidden_node_number[hidden_layer_number_arg - 1]+ 1)*(i) + 1+ j, current_change, i,j,i,output_error[i],hidden_node_number_index + j, hidden_node_output[hidden_node_number_index + j]); #endif } } //compute weight change of hidden node last layer to 2 layer if (hidden_layer_number_arg > 1) { for(i = hidden_layer_number_arg - 1; i >= 1; i--) { weight_index = weight_index - (hidden_node_number[i - 1]+1)*hidden_node_number[i]; hidden_node_number_index = hidden_node_number_index - hidden_node_number[i - 1]; delta = 0.0; for (j = 0; j < hidden_node_number[i]; j++) { delta = (1.0/set_size_arg*hidden_node_error[hidden_node_number_index + hidden_node_number[i - 1] + j]); threshold_change = delta; result_data[weight_index + (hidden_node_number[i - 1] + 1) * (j)] = Float8GetDatum(threshold_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f ", weight_index + (hidden_node_number[i - 1] + 1) * (j), threshold_change); #endif for(k = 0; k < hidden_node_number[i - 1]; k++) { current_change = delta * hidden_node_output[hidden_node_number_index + k]; result_data[weight_index + (hidden_node_number[i - 1] + 1) * (j) + 1 + k] = Float8GetDatum(current_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f i:%d, j:%d k:%d hidden_node_error[%d]:%f hidden_node_output[%d]:%f", weight_index + (hidden_node_number[i - 1] + 1) * (j) + 1 + k, current_change,i,j,k,hidden_node_number_index + hidden_node_number[i - 1] + j, hidden_node_error[hidden_node_number_index + hidden_node_number[i - 1] + j], hidden_node_number_index + k,hidden_node_output[hidden_node_number_index + k]); #endif } } } } //compute weight change of first layer hidden node weight_index = 0; hidden_node_number_index = 0; delta = 0.0; for(j = 0; j < hidden_node_number[0]; j++) { delta = 1.0/set_size_arg*hidden_node_error[hidden_node_number_index + j]; threshold_change = delta; result_data[weight_index + (columns_count+1)*(j)] = Float8GetDatum(threshold_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f ", weight_index + (columns_count+1)*(j), threshold_change); #endif for(k = 0; k < columns_count; k++) { current_change = delta*input[k]; result_data[weight_index + (columns_count+1)*(j) + k + 1] = Float8GetDatum(current_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f j:%d k:%d hidden_node_error[%d]:%f input[%d]:%f", weight_index + (columns_count+1)*(j) + k + 1, current_change,j,k,hidden_node_number_index + j, hidden_node_error[hidden_node_number_index + j], k, input[k]); #endif } } result_data[weight_count] = Float8GetDatum(total_error); ndims = 1; dims = (int *) palloc(sizeof(int)); dims[0] = result_count; lbs = (int *) palloc(sizeof(int)); lbs[0] = 1; result = construct_md_array((void *)result_data, result_nulls, ndims, dims, lbs, result_eltype, result_typlen, result_typbyval, result_typalign); // pfree(result); pfree(weight_data); pfree(columns_data); pfree(input_range_data); pfree(input_base_data); pfree(hidden_node_number_data); pfree(result_data); pfree(weight_nulls); pfree(columns_nulls); pfree(input_range_nulls); pfree(input_base_nulls); pfree(hidden_node_number_nulls); pfree(result_nulls); pfree(input); pfree(output); pfree(lbs); pfree(dims); pfree(hidden_node_output); pfree(weight); pfree(hidden_node_number); pfree(hidden_node_error); pfree(output_error); PG_RETURN_ARRAYTYPE_P(result); }