Exemplo n.º 1
0
/*
 * build_regexp_matches_result - build output array for current match
 */
static array_s *build_regexp_matches_result(regexp_matches_ctx * matchctx)
{
	datum_t *elems = matchctx->elems;
	bool *nulls = matchctx->nulls;
	int dims[1];
	int lbs[1];
	int loc;
	int i;

	/* Extract matching substrings from the original string */
	loc = matchctx->next_match * matchctx->npatterns * 2;
	for (i = 0; i < matchctx->npatterns; i++) {
		int so = matchctx->match_locs[loc++];
		int eo = matchctx->match_locs[loc++];

		if (so < 0 || eo < 0) {
			elems[i] = (datum_t) 0;
			nulls[i] = true;
		} else {
			elems[i] = DIRECT_FC3(text_substr, PTR_TO_D(matchctx->orig_str),
				INT32_TO_D(so + 1), INT32_TO_D(eo - so));
			nulls[i] = false;
		}
	}

	/* And form an array */
	dims[0] = matchctx->npatterns;
	lbs[0] = 1;
	/* XXX: this hardcodes assumptions about the text type */
	return construct_md_array(elems, nulls, 1, dims, lbs, TEXTOID, -1, false, 'i');
}
Exemplo n.º 2
0
Datum
hstore_slice_to_array(PG_FUNCTION_ARGS)
{
    HStore	   *hs = PG_GETARG_HS(0);
    HEntry	   *entries = ARRPTR(hs);
    char	   *ptr = STRPTR(hs);
    ArrayType  *key_array = PG_GETARG_ARRAYTYPE_P(1);
    ArrayType  *aout;
    Datum	   *key_datums;
    bool	   *key_nulls;
    Datum	   *out_datums;
    bool	   *out_nulls;
    int			key_count;
    int			i;

    deconstruct_array(key_array,
                      TEXTOID, -1, false, 'i',
                      &key_datums, &key_nulls, &key_count);

    if (key_count == 0)
    {
        aout = construct_empty_array(TEXTOID);
        PG_RETURN_POINTER(aout);
    }

    out_datums = palloc(sizeof(Datum) * key_count);
    out_nulls = palloc(sizeof(bool) * key_count);

    for (i = 0; i < key_count; ++i)
    {
        text	   *key = (text *) DatumGetPointer(key_datums[i]);
        int			idx;

        if (key_nulls[i])
            idx = -1;
        else
            idx = hstoreFindKey(hs, NULL, VARDATA(key), VARSIZE(key) - VARHDRSZ);

        if (idx < 0 || HS_VALISNULL(entries, idx))
        {
            out_nulls[i] = true;
            out_datums[i] = (Datum) 0;
        }
        else
        {
            out_datums[i] = PointerGetDatum(
                                cstring_to_text_with_len(HS_VAL(entries, ptr, idx),
                                        HS_VALLEN(entries, idx)));
            out_nulls[i] = false;
        }
    }

    aout = construct_md_array(out_datums, out_nulls,
                              ARR_NDIM(key_array),
                              ARR_DIMS(key_array),
                              ARR_LBOUND(key_array),
                              TEXTOID, -1, false, 'i');

    PG_RETURN_POINTER(aout);
}
Exemplo n.º 3
0
/*
 * used by text_to_array() in varlena.c
 */
array_s *create_singleton_array(struct fc_info* fcinfo, oid_t element_type,
	datum_t element, bool isNull, int ndims)
{
	datum_t dvalues[1];
	bool nulls[1];
	int16 typlen;
	bool typbyval;
	char typalign;
	int dims[MAXDIM];
	int lbs[MAXDIM];
	int i;
	array_meta_s *my_extra;

	if (ndims < 1)
		ereport(ERROR, (
		errcode(E_INVALID_PARAMETER_VALUE),
		errmsg("invalid number of dimensions: %d", ndims)));

	if (ndims > MAXDIM)
		ereport(ERROR, (
		errcode(E_PROGRAM_LIMIT_EXCEEDED),
		errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
			ndims, MAXDIM)));

	dvalues[0] = element;
	nulls[0] = isNull;
	for (i = 0; i < ndims; i++) {
		dims[i] = 1;
		lbs[i] = 1;
	}

	/*
	 * We arrange to look up info about element type only once per series of
	 * calls, assuming the element type doesn't change underneath us.
	 */
	my_extra = (array_meta_s *) fcinfo->flinfo->fn_extra;
	if (my_extra == NULL) {
		fcinfo->flinfo->fn_extra = mctx_alloc(fcinfo->flinfo->fn_mcxt, 
		 	sizeof(array_meta_s));
		my_extra = (array_meta_s *) fcinfo->flinfo->fn_extra;
		my_extra->element_type = ~element_type;
	}

	if (my_extra->element_type != element_type) {
		/* Get info about element type */
		get_typlenbyvalalign(element_type, &my_extra->typlen, &my_extra->typbyval, 
			&my_extra->typalign);
		my_extra->element_type = element_type;
	}

	typlen = my_extra->typlen;
	typbyval = my_extra->typbyval;
	typalign = my_extra->typalign;

	return construct_md_array(dvalues, nulls, ndims, dims, lbs, element_type, typlen,
		typbyval, typalign);
}
Exemplo n.º 4
0
Arquivo: putline.c Projeto: 50wu/gpdb
Datum
dbms_output_get_lines(PG_FUNCTION_ARGS)
{
	TupleDesc	tupdesc;
	Datum		result;
	HeapTuple	tuple;
	Datum		values[2];
	bool		nulls[2] = { false, false };
	text	   *line;

	int32		max_lines = PG_GETARG_INT32(0);
	int32		n;
    ArrayBuildState *astate = NULL;

	/* Build a tuple descriptor for our result type */
	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
		elog(ERROR, "return type must be a row type");

	for (n = 0; n < max_lines && (line = dbms_output_next()) != NULL; n++)
	{
		astate = accumArrayResult(astate, PointerGetDatum(line), false,
					TEXTOID, CurrentMemoryContext);
	}

	/* 0: lines as text array */
	if (n > 0)
		values[0] = makeArrayResult(astate, CurrentMemoryContext);
	else
	{
		int16		typlen;
		bool		typbyval;
		char		typalign;
		ArrayType  *arr;

		get_typlenbyvalalign(TEXTOID, &typlen, &typbyval, &typalign);
		arr = construct_md_array(
			NULL,
#if PG_VERSION_NUM >= 80200
			NULL,
#endif
			0, NULL, NULL, TEXTOID, typlen, typbyval, typalign);
		values[0] = PointerGetDatum(arr);
	}

	/* 1: # of lines as integer */
	values[1] = Int32GetDatum(n);

	tuple = heap_form_tuple(tupdesc, values, nulls);
	result = HeapTupleGetDatum(tuple);

	PG_RETURN_DATUM(result);
}
Exemplo n.º 5
0
/*
 * build_regexp_matches_result - build output array for current match
 */
static ArrayType *
build_regexp_matches_result(regexp_matches_ctx *matchctx)
{
	char	   *buf = matchctx->conv_buf;
	int			bufsiz PG_USED_FOR_ASSERTS_ONLY = matchctx->conv_bufsiz;
	Datum	   *elems = matchctx->elems;
	bool	   *nulls = matchctx->nulls;
	int			dims[1];
	int			lbs[1];
	int			loc;
	int			i;

	/* Extract matching substrings from the original string */
	loc = matchctx->next_match * matchctx->npatterns * 2;
	for (i = 0; i < matchctx->npatterns; i++)
	{
		int			so = matchctx->match_locs[loc++];
		int			eo = matchctx->match_locs[loc++];

		if (so < 0 || eo < 0)
		{
			elems[i] = (Datum) 0;
			nulls[i] = true;
		}
		else if (buf)
		{
			int		len = pg_wchar2mb_with_len(matchctx->wide_str + so,
											   buf,
											   eo - so);
			Assert(len < bufsiz);
			elems[i] = PointerGetDatum(cstring_to_text_with_len(buf, len));
			nulls[i] = false;
		}
		else
		{
			elems[i] = DirectFunctionCall3(text_substr,
										 PointerGetDatum(matchctx->orig_str),
										   Int32GetDatum(so + 1),
										   Int32GetDatum(eo - so));
			nulls[i] = false;
		}
	}

	/* And form an array */
	dims[0] = matchctx->npatterns;
	lbs[0] = 1;
	/* XXX: this hardcodes assumptions about the text type */
	return construct_md_array(elems, nulls, 1, dims, lbs,
							  TEXTOID, -1, false, 'i');
}
Exemplo n.º 6
0
static ArrayType *
hstore_to_array_internal(HStore *hs, int ndims)
{
    HEntry	   *entries = ARRPTR(hs);
    char	   *base = STRPTR(hs);
    int			count = HS_COUNT(hs);
    int			out_size[2] = {0, 2};
    int			lb[2] = {1, 1};
    Datum	   *out_datums;
    bool	   *out_nulls;
    int			i;

    Assert(ndims < 3);

    if (count == 0 || ndims == 0)
        return construct_empty_array(TEXTOID);

    out_size[0] = count * 2 / ndims;
    out_datums = palloc(sizeof(Datum) * count * 2);
    out_nulls = palloc(sizeof(bool) * count * 2);

    for (i = 0; i < count; ++i)
    {
        text	   *key = cstring_to_text_with_len(HS_KEY(entries, base, i),
                          HS_KEYLEN(entries, i));

        out_datums[i * 2] = PointerGetDatum(key);
        out_nulls[i * 2] = false;

        if (HS_VALISNULL(entries, i))
        {
            out_datums[i * 2 + 1] = (Datum) 0;
            out_nulls[i * 2 + 1] = true;
        }
        else
        {
            text	   *item = cstring_to_text_with_len(HS_VAL(entries, base, i),
                               HS_VALLEN(entries, i));

            out_datums[i * 2 + 1] = PointerGetDatum(item);
            out_nulls[i * 2 + 1] = false;
        }
    }

    return construct_md_array(out_datums, out_nulls,
                              ndims, out_size, lb,
                              TEXTOID, -1, false, 'i');
}
Exemplo n.º 7
0
static Datum
PLySequence_ToArray(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
{
	ArrayType  *array;
	Datum		rv;
	int			i;
	Datum	   *elems;
	bool	   *nulls;
	int			len;
	int			lbs;

	Assert(plrv != Py_None);

	if (!PySequence_Check(plrv))
		PLy_elog(ERROR, "return value of function with array return type is not a Python sequence");

	len = PySequence_Length(plrv);
	elems = palloc(sizeof(*elems) * len);
	nulls = palloc(sizeof(*nulls) * len);

	for (i = 0; i < len; i++)
	{
		PyObject   *obj = PySequence_GetItem(plrv, i);

		if (obj == Py_None)
			nulls[i] = true;
		else
		{
			nulls[i] = false;
			elems[i] = arg->elm->func(arg->elm, -1, obj);
		}
		Py_XDECREF(obj);
	}

	lbs = 1;
	array = construct_md_array(elems, nulls, 1, &len, &lbs,
							   get_base_element_type(arg->typoid), arg->elm->typlen, arg->elm->typbyval, arg->elm->typalign);

	/*
	 * If the result type is a domain of array, the resulting array must be
	 * checked.
	 */
	rv = PointerGetDatum(array);
	if (get_typtype(arg->typoid) == TYPTYPE_DOMAIN)
		domain_check(rv, false, arg->typoid, &arg->typfunc.fn_extra, arg->typfunc.fn_mcxt);
	return rv;
}
Exemplo n.º 8
0
ArrayType *
create_md_guc_array(List *guc_list, int elems, int ndims)
{
	ArrayType  *array;
	Datum	   *darray;
	int			dims[ndims];
	int			lbs[1];

	darray = create_guc_datum_array(guc_list, elems * ndims);

	dims[0] = elems;
	dims[1] = elems;
	lbs[0] = 1;
	array = construct_md_array(darray, NULL, ndims, dims, lbs,
							   TEXTOID, TEXT_TYPLEN, TEXT_TYPBYVAL, TEXT_TYPALIGN);
	pfree(darray);
	return array;
}
Exemplo n.º 9
0
Datum
hstore_avals(PG_FUNCTION_ARGS)
{
    HStore	   *hs = PG_GETARG_HS(0);
    Datum	   *d;
    bool	   *nulls;
    ArrayType  *a;
    HEntry	   *entries = ARRPTR(hs);
    char	   *base = STRPTR(hs);
    int			count = HS_COUNT(hs);
    int			lb = 1;
    int			i;

    if (count == 0)
    {
        a = construct_empty_array(TEXTOID);
        PG_RETURN_POINTER(a);
    }

    d = (Datum *) palloc(sizeof(Datum) * count);
    nulls = (bool *) palloc(sizeof(bool) * count);

    for (i = 0; i < count; ++i)
    {
        if (HS_VALISNULL(entries, i))
        {
            d[i] = (Datum) 0;
            nulls[i] = true;
        }
        else
        {
            text	   *item = cstring_to_text_with_len(HS_VAL(entries, base, i),
                               HS_VALLEN(entries, i));

            d[i] = PointerGetDatum(item);
            nulls[i] = false;
        }
    }

    a = construct_md_array(d, nulls, 1, &count, &lb,
                           TEXTOID, -1, false, 'i');

    PG_RETURN_POINTER(a);
}
Exemplo n.º 10
0
static Datum
PLySequence_ToArray(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
{
	ArrayType  *array;
	int			i;
	Datum	   *elems;
	bool	   *nulls;
	int			len;
	int			lbs;

	Assert(plrv != Py_None);

	if (!PySequence_Check(plrv))
		PLy_elog(ERROR, "return value of function with array return type is not a Python sequence");

	len = PySequence_Length(plrv);
	elems = palloc(sizeof(*elems) * len);
	nulls = palloc(sizeof(*nulls) * len);

	for (i = 0; i < len; i++)
	{
		PyObject   *obj = PySequence_GetItem(plrv, i);

		if (obj == Py_None)
			nulls[i] = true;
		else
		{
			nulls[i] = false;

			/*
			 * We don't support arrays of row types yet, so the first argument
			 * can be NULL.
			 */
			elems[i] = arg->elm->func(arg->elm, -1, obj);
		}
		Py_XDECREF(obj);
	}

	lbs = 1;
	array = construct_md_array(elems, nulls, 1, &len, &lbs,
							   get_element_type(arg->typoid), arg->elm->typlen, arg->elm->typbyval, arg->elm->typalign);
	return PointerGetDatum(array);
}
Exemplo n.º 11
0
static Datum _Array_coerceObject(Type self, jobject objArray)
{
	ArrayType* v;
	jsize idx;
	int    lowerBound = 1;
	Type   elemType = Type_getElementType(self);
	int    nElems   = (int)JNI_getArrayLength((jarray)objArray);
	Datum* values   = (Datum*)palloc(nElems * sizeof(Datum) + nElems * sizeof(bool));
	bool*  nulls    = (bool*)(values + nElems);

	for(idx = 0; idx < nElems; ++idx)
	{
		jobject obj = JNI_getObjectArrayElement(objArray, idx);
		if(obj == 0)
		{
			nulls[idx] = true;
			values[idx] = 0;
		}
		else
		{
			nulls[idx] = false;
			values[idx] = Type_coerceObject(elemType, obj);
			JNI_deleteLocalRef(obj);
		}
	}

	v = construct_md_array(
		values,
		nulls,
		1,
		&nElems,
		&lowerBound,
		Type_getOid(elemType),
		Type_getLength(elemType),
		Type_isByValue(elemType),
		Type_getAlign(elemType));

	pfree(values);
	PG_RETURN_ARRAYTYPE_P(v);
}
Exemplo n.º 12
0
/*!
 * scalar function taking an mfv sketch, returning a histogram of
 * its most frequent values
 */
Datum __mfvsketch_final(PG_FUNCTION_ARGS)
{
    bytea *      transblob = PG_GETARG_BYTEA_P(0);
    mfvtransval *transval = NULL;
    ArrayType *  retval;
    uint32       i;
    int          dims[2], lbs[2];
    /* Oid     typInput, typIOParam; */
    Oid          outFuncOid;
    bool         typIsVarlena;
    int16        typlen;
    bool         typbyval;
    char         typalign;
    char         typdelim;
    Oid          typioparam;
    Oid          typiofunc;


    if (PG_ARGISNULL(0)) PG_RETURN_NULL();
    if (VARSIZE(transblob) < MFV_TRANSVAL_SZ(0)) PG_RETURN_NULL();

    check_mfvtransval(transblob);
    transval = (mfvtransval *)VARDATA(transblob);
    /*
     * We only declare the variable-length array histo here after some sanity
     * checking. We risk a stack overflow otherwise. In particular, we need to
     * make sure that transval->max_mfvs is initialized. It might not be if the
     * (strict) transition function is never called. (MADLIB-254)
     */
    Datum        histo[transval->max_mfvs][2];

    qsort(transval->mfvs, transval->next_mfv, sizeof(offsetcnt), cnt_cmp_desc);
    getTypeOutputInfo(INT8OID,
                      &outFuncOid,
                      &typIsVarlena);

    for (i = 0; i < transval->next_mfv; i++) {
        void *tmpp = mfv_transval_getval(transblob,i);
        Datum curval = PointerExtractDatum(tmpp, transval->typByVal);
        char *countbuf =
            OidOutputFunctionCall(outFuncOid,
                                  Int64GetDatum(transval->mfvs[i].cnt));
        char *valbuf = OidOutputFunctionCall(transval->outFuncOid, curval);

        histo[i][0] = PointerGetDatum(cstring_to_text(valbuf));
        histo[i][1] = PointerGetDatum(cstring_to_text(countbuf));
        pfree(countbuf);
        pfree(valbuf);
    }

    /*
     * Get info about element type
     */
    get_type_io_data(TEXTOID, IOFunc_output,
                     &typlen, &typbyval,
                     &typalign, &typdelim,
                     &typioparam, &typiofunc);

    dims[0] = i;
    dims[1] = 2;
    lbs[0] = lbs[1] = 0;
    retval = construct_md_array((Datum *)histo,
                                NULL,
                                2,
                                dims,
                                lbs,
                                TEXTOID,
                                -1,
                                0,
                                'i');
    PG_RETURN_ARRAYTYPE_P(retval);
}
static void
grab_ExecutorEnd(QueryDesc * queryDesc)
{
	Datum           values[10];
	bool            nulls[10] = {false, false, false, false, false, false, false, false, false, false};
	Relation        dump_heap;
	RangeVar       *dump_table_rv;
	HeapTuple       tuple;
	Oid             namespaceId;

	/* lookup schema */
	namespaceId = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(EXTENSION_SCHEMA));
	if (OidIsValid(namespaceId)) {
		/* lookup table */
		if (OidIsValid(get_relname_relid(EXTENSION_LOG_TABLE, namespaceId))) {

			/* get table heap */
			dump_table_rv = makeRangeVar(EXTENSION_SCHEMA, EXTENSION_LOG_TABLE, -1);
			dump_heap = heap_openrv(dump_table_rv, RowExclusiveLock);

			/* transaction info */
			values[0] = Int32GetDatum(GetCurrentTransactionId());
			values[1] = Int32GetDatum(GetCurrentCommandId(false));
			values[2] = Int32GetDatum(MyProcPid);
			values[3] = Int32GetDatum(GetUserId());

			/* query timing */
			if (queryDesc->totaltime != NULL) {
				InstrEndLoop(queryDesc->totaltime);
				values[4] = TimestampGetDatum(
							      TimestampTzPlusMilliseconds(GetCurrentTimestamp(),
				  (queryDesc->totaltime->total * -1000.0)));
				values[5] = Float8GetDatum(queryDesc->totaltime->total);
			} else {
				nulls[4] = true;
				nulls[5] = true;
			}

			/* query command type */
			values[6] = Int32GetDatum(queryDesc->operation);

			/* query text */
			values[7] = CStringGetDatum(
				    cstring_to_text(queryDesc->sourceText));

			/* query params */
			if (queryDesc->params != NULL) {
				int             numParams = queryDesc->params->numParams;
				Oid             out_func_oid, ptype;
				Datum           pvalue;
				bool            isvarlena;
				FmgrInfo       *out_functions;

				bool            arr_nulls[numParams];
				size_t          arr_nelems = (size_t) numParams;
				Datum          *arr_val_elems = palloc(sizeof(Datum) * arr_nelems);
				Datum          *arr_typ_elems = palloc(sizeof(Datum) * arr_nelems);
				char            elem_val_byval, elem_val_align, elem_typ_byval,
				                elem_typ_align;
				int16           elem_val_len, elem_typ_len;
				int             elem_dims[1], elem_lbs[1];

				int paramno;

				/* init */
				out_functions = (FmgrInfo *) palloc(
					    (numParams) * sizeof(FmgrInfo));
				get_typlenbyvalalign(TEXTOID, &elem_val_len, &elem_val_byval, &elem_val_align);
				get_typlenbyvalalign(REGTYPEOID, &elem_typ_len, &elem_typ_byval, &elem_typ_align);
				elem_dims[0] = arr_nelems;
				elem_lbs[0] = 1;

				for (paramno = 0; paramno < numParams; paramno++) {
					pvalue = queryDesc->params->params[paramno].value;
					ptype = queryDesc->params->params[paramno].ptype;
					getTypeOutputInfo(ptype, &out_func_oid, &isvarlena);
					fmgr_info(out_func_oid, &out_functions[paramno]);

					arr_typ_elems[paramno] = ptype;

					arr_nulls[paramno] = true;
					if (!queryDesc->params->params[paramno].isnull) {
						arr_nulls[paramno] = false;
						arr_val_elems[paramno] = PointerGetDatum(
							    cstring_to_text(
									    OutputFunctionCall(&out_functions[paramno], pvalue)));
					}
				}
				values[8] = PointerGetDatum(
							 construct_md_array(
							      arr_val_elems,
								  arr_nulls,
									  1,
								  elem_dims,
								   elem_lbs,
								    TEXTOID,
							       elem_val_len,
							     elem_val_byval,
							   elem_val_align));
				values[9] = PointerGetDatum(
							    construct_array(
							      arr_typ_elems,
								 arr_nelems,
								 REGTYPEOID,
							       elem_typ_len,
							     elem_typ_byval,
							   elem_typ_align));

				pfree(out_functions);
				pfree(arr_val_elems);

			} else {
				nulls[8] = true;
				nulls[9] = true;
			}

			/* insert */
			tuple = heap_form_tuple(dump_heap->rd_att, values, nulls);
			simple_heap_insert(dump_heap, tuple);
			heap_close(dump_heap, RowExclusiveLock);
		}
	}
	if (prev_ExecutorEnd)
		prev_ExecutorEnd(queryDesc);
	else
		standard_ExecutorEnd(queryDesc);
}
Exemplo n.º 14
0
static PyObj
array_item(PyObj self, Py_ssize_t item)
{
	volatile PyObj rob = NULL;
	PyPgTypeInfo typinfo, atypinfo;
	ArrayType *at;
	Datum rd;
	bool isnull = false;
	int index = (int) item;
	PyObj elm;

	elm = PyPgType_GetElementType(Py_TYPE(self));
	typinfo = PyPgTypeInfo(elm);
	atypinfo = PyPgTypeInfo(Py_TYPE(self));
	at = DatumGetArrayTypeP(PyPgObject_GetDatum(self));

	/* convert index */
	++index;

	if (ARR_NDIM(at) == 0)
	{
		PyErr_SetString(PyExc_IndexError, "empty array");
		return(NULL);
	}

	/*
	 * Note that the comparison is '>', not '>='.
	 */
	if (index > ARR_DIMS(at)[0])
	{
		PyErr_Format(PyExc_IndexError, "index %d out of range %d",
			item, ARR_DIMS(at)[0]);
		return(NULL);
	}

	/*
	 * Single dimenion array? Get an element.
	 */
	if (ARR_NDIM(at) == 1)
	{
		PG_TRY();
		{
			rd = array_ref(at, 1, &index, atypinfo->typlen,
				typinfo->typlen, typinfo->typbyval, typinfo->typalign, &isnull);

			if (isnull)
			{
				rob = Py_None;
				Py_INCREF(rob);
			}
			else
			{
				/*
				 * It points into the array structure, so there's no need to free.
				 */
				rob = PyPgObject_New(elm, rd);
			}
		}
		PG_CATCH();
		{
			Py_XDECREF(rob);
			rob = NULL;
			PyErr_SetPgError(false);
			return(NULL);
		}
		PG_END_TRY();
	}
	else
	{
		ArrayType *rat;
		int lower[MAXDIM] = {index,0,};
		int upper[MAXDIM] = {index,0,};

		/*
		 * Multiple dimensions, so get a slice.
		 */
		PG_TRY();
		{
			ArrayType *xat;
			Datum *elements;
			bool *nulls;
			int nelems;
			int ndims, i;
			int lbs[MAXDIM];
			int dims[MAXDIM];

			xat = array_get_slice(at, 1, upper, lower, atypinfo->typlen,
						typinfo->typlen, typinfo->typbyval, typinfo->typalign);

			/*
			 * Eventually, this should probably be changed to change the already
			 * allocated ArrayType at 'xat', but for now use the available
			 * interfaces for creating the expected result.
			 */
			deconstruct_array(xat,
				typinfo->typoid, typinfo->typlen, typinfo->typbyval, typinfo->typalign,
				&elements, &nulls, &nelems
			);

			/*
			 * Alter dims, lbs, and ndims: we are removing the first dimension.
			 */
			ndims = ARR_NDIM(xat);
			for (i = 1; i < ndims; ++i)
				lbs[i-1] = ARR_LBOUND(xat)[i];
			for (i = 1; i < ndims; ++i)
				dims[i-1] = ARR_DIMS(xat)[i];
			--ndims;

			/*
			 * Construct the expected result to a Python itemget call.
			 */
			rat = construct_md_array(elements, nulls, ndims, dims, lbs,
				typinfo->typoid, typinfo->typlen, typinfo->typbyval, typinfo->typalign);

			pfree(elements);
			pfree(nulls);
			pfree(xat);

			rob = PyPgObject_New(Py_TYPE(self), PointerGetDatum(rat));
			pfree(rat);
		}
		PG_CATCH();
		{
			PyErr_SetPgError(false);
			return(NULL);
		}
		PG_END_TRY();
	}

	return(rob);
}
Exemplo n.º 15
0
/*
 * array_from_list - given an element type and a list(), build an array
 * using the described structure.
 *
 * Sets a Python error and returns NULL on failure.
 */
static ArrayType *
array_from_list_and_info(PyObj element_type, PyObj listob, int elemmod,
	int ndims, int *dims, int *lbs)
{
	PyPgTypeInfo typinfo = PyPgTypeInfo(element_type);
	unsigned int nelems;
	int i;
	Datum * volatile datums = NULL;
	bool * volatile nulls = NULL;
	ArrayType * volatile rat = NULL;

	Assert(PyList_CheckExact(listob));

	nelems = PyList_GET_SIZE(listob);

	PG_TRY();
	{
		/*
		 * palloc0 as cleanup in the PG_CATCH() will depend on this.
		 */
		nulls = palloc0(sizeof(bool) * nelems);
		datums = palloc0(sizeof(Datum) * nelems);

		for (i = 0; i < nelems; ++i)
		{
			PyPgType_DatumNew(element_type, PyList_GET_ITEM(listob, i),
				elemmod, (Datum *) &(datums[i]), (bool *) &(nulls[i]));
		}

		/*
		 * Everything has been allocated, make the array.
		 */
		rat = construct_md_array(
			(Datum *) datums, (bool *) nulls,
			ndims, dims, lbs,
			typinfo->typoid,
			typinfo->typlen,
			typinfo->typbyval,
			typinfo->typalign);

		/*
		 * Cleanup.
		 */
		if (!typinfo->typbyval)
		{
			for (i = 0; i < nelems; ++i)
			{
				/*
				 * Array construction completed successfully,
				 * so go over the entire array of datums.
				 */
				if (!nulls[i])
					pfree(DatumGetPointer(datums[i]));
			}
		}
		pfree((bool *) nulls);
		pfree((Datum *) datums);
	}
	PG_CATCH();
	{
		/*
		 * Try and cleanup as much memory as possible.
		 *
		 * Currently, this code will run in the procedure context,
		 * so whatever leaks here will remain allocated for the duration of the
		 * procedure. If failure is often the part of a loop, the leaks could
		 * be problematic.
		 */

		if (rat != NULL)
		{
			/*
			 * When rat != NULL, failure occurred after the array
			 * was built, which means it had trouble freeing the resources.
			 * Attempt to free rat, but leave it at that.
			 */
			pfree((char *) rat);
		}
		else
		{
			if (datums != NULL && nulls != NULL)
			{
				if (!typinfo->typbyval)
				{
					/*
					 * This is a bit different from the non-error case;
					 * rather than pfree'ing everything, we watch for
					 * NULL pointers..
					 */
					for (i = 0; i < nelems; ++i)
					{
						char *p = DatumGetPointer(datums[i]);
						if (nulls[i])
							continue;

						if (PointerIsValid(p))
							pfree(p);
						else
							break;
					}
				}
			}

			if (datums != NULL)
				pfree((Datum *) datums);
			if (nulls != NULL)
				pfree((bool *) nulls);
		}

		PyErr_SetPgError(false);
		rat = NULL;
	}
	PG_END_TRY();

	return((ArrayType *) rat);
}
Exemplo n.º 16
0
/*
 * array_from_py_list - given an element type and a list(), build an array
 */
static ArrayType *
array_from_py_list(PyObj element_type, PyObj listob, int elemmod)
{
	PyPgTypeInfo typinfo = PyPgTypeInfo(element_type);
	Datum * volatile datums = NULL;
	bool * volatile nulls = NULL;
	unsigned int nelems;
	int i, ndims;
	int dims[MAXDIM];
	int lbs[MAXDIM];
	ArrayType *rat = NULL;

	ndims = py_list_dimensions(listob, dims);
	Assert(ndims <= MAXDIM);

	/*
	 * From the dimensions, calculate the expected number of elements.
	 * At this point it is not known if the array is balanced
	 */
	nelems = dims[ndims-1];
	for (i = ndims-2; i > -1; --i)
	{
		unsigned int n = nelems * dims[i];
		if (n < nelems)
		{
			elog(ERROR, "too many elements for array");
		}
		nelems = n;
	}

	if (nelems == 0 && ndims > 1)
		elog(ERROR, "malformed nesting of list objects");

	PG_TRY();
	{
		/*
		 * palloc0 as cleanup in the PG_CATCH() will depend on this.
		 */
		nulls = palloc0(sizeof(bool) * nelems);
		datums = palloc0(sizeof(Datum) * nelems);

		/*
		 * elog's on failure, this will validate the balance/sizes of the
		 * dimensions.
		 */
		fill_elements(element_type, listob, elemmod, nelems, ndims, dims,
			(Datum *) datums, (bool *) nulls);

		/*
		 * Arrays built from lists don't support custom lower bounds,
		 * so initialize it to the default '1'.
		 */
		for (i = 0; i < ndims; ++i)
			lbs[i] = 1;

		/*
		 * Everything has been allocated, make the array.
		 */
		rat = construct_md_array(
			(Datum *) datums, (bool *) nulls,
			ndims, dims, lbs,
			typinfo->typoid,
			typinfo->typlen,
			typinfo->typbyval,
			typinfo->typalign);

		/*
		 * Cleanup.
		 */
		if (!typinfo->typbyval)
		{
			for (i = 0; i < nelems; ++i)
			{
				/*
				 * Array construction completed successfully,
				 * so go over the entire array of datums.
				 */
				if (!nulls[i])
					pfree(DatumGetPointer(datums[i]));
			}
		}
		pfree((bool *) nulls);
		pfree((Datum *) datums);
	}
	PG_CATCH();
	{
		/*
		 * Try and cleanup as much memory as possible.
		 *
		 * Currently, this code will run in the procedure context,
		 * so whatever leaks here will remain allocated for the duration of the
		 * procedure.
		 */

		if (rat != NULL)
		{
			/*
			 * When rat != NULL, failure occurred after the array
			 * was built, which means it had trouble freeing the resources.
			 * Attempt to free rat, but leave it at that.
			 */
			pfree(rat);
		}
		else
		{
			if (datums != NULL && nulls != NULL)
			{
				if (!typinfo->typbyval)
				{
					/*
					 * This is a bit different from the non-error case;
					 * rather than pfree'ing everything, we watch for
					 * NULL pointers..
					 */
					for (i = 0; i < nelems; ++i)
					{
						char *p = DatumGetPointer(datums[i]);
						if (nulls[i])
							continue;

						if (PointerIsValid(p))
							pfree(p);
						else
							break;
					}
				}
			}

			if (datums != NULL)
				pfree((Datum *) datums);
			if (nulls != NULL)
				pfree((bool *) nulls);
		}

		PG_RE_THROW();
	}
	PG_END_TRY();

	return(rat);
}
Exemplo n.º 17
0
static void
FunctionParserInit(FunctionParser *self, Checker *checker, const char *infile, TupleDesc desc, bool multi_process, Oid collation)
{
	int					i;
	ParsedFunction		function;
	int					nargs;
	Oid					funcid;
	HeapTuple			ftup;
	Form_pg_proc		pp;
	bool				tupledesc_matched = false;

	if (pg_strcasecmp(infile, "stdin") == 0)
		ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						errmsg("cannot load from STDIN in the case of \"TYPE = FUNCTION\"")));

	if (checker->encoding != -1)
		ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						errmsg("does not support parameter \"ENCODING\" in \"TYPE = FUNCTION\"")));

	function = ParseFunction(infile, false);

	funcid = function.oid;
	fmgr_info(funcid, &self->flinfo);

	if (!self->flinfo.fn_retset)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("function must return set")));

	ftup = SearchSysCache(PROCOID, ObjectIdGetDatum(funcid), 0, 0, 0);
	pp = (Form_pg_proc) GETSTRUCT(ftup);

	/* Check data type of the function result value */
	if (pp->prorettype == desc->tdtypeid && desc->tdtypeid != RECORDOID)
		tupledesc_matched = true;
	else if (pp->prorettype == RECORDOID)
	{
		TupleDesc	resultDesc = NULL;

		/* Check for OUT parameters defining a RECORD result */
		resultDesc = build_function_result_tupdesc_t(ftup);

		if (resultDesc)
		{
			tupledesc_match(desc, resultDesc);
			tupledesc_matched = true;
			FreeTupleDesc(resultDesc);
		}
	}
	else if (get_typtype(pp->prorettype) != TYPTYPE_COMPOSITE)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function return data type and target table data type do not match")));

	if (tupledesc_matched && checker->tchecker)
		checker->tchecker->status = NO_COERCION;

	/*
	 * assign arguments
	 */
	nargs = function.nargs;
	for (i = 0;
#if PG_VERSION_NUM >= 80400
		i < nargs - function.nvargs;
#else
		i < nargs;
#endif
		++i)
	{
		if (function.args[i] == NULL)
		{
			if (self->flinfo.fn_strict)
				ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					errmsg("function is strict, but argument %d is NULL", i)));
			self->fcinfo.argnull[i] = true;
		}
		else
		{
			Oid			typinput;
			Oid			typioparam;

			getTypeInputInfo(pp->proargtypes.values[i], &typinput, &typioparam);
			self->fcinfo.arg[i] = OidInputFunctionCall(typinput,
									(char *) function.args[i], typioparam, -1);
			self->fcinfo.argnull[i] = false;
			pfree(function.args[i]);
		}
	}

	/*
	 * assign variadic arguments
	 */
#if PG_VERSION_NUM >= 80400
	if (function.nvargs > 0)
	{
		int			nfixedarg;
		Oid			func;
		Oid			element_type;
		int16		elmlen;
		bool		elmbyval;
		char		elmalign;
		char		elmdelim;
		Oid			elmioparam;
		Datum	   *elems;
		bool	   *nulls;
		int			dims[1];
		int			lbs[1];
		ArrayType  *arry;

		nfixedarg = i;
		element_type = pp->provariadic;

		/*
		 * Get info about element type, including its input conversion proc
		 */
		get_type_io_data(element_type, IOFunc_input,
						 &elmlen, &elmbyval, &elmalign, &elmdelim,
						 &elmioparam, &func);

		elems = (Datum *) palloc(function.nvargs * sizeof(Datum));
		nulls = (bool *) palloc0(function.nvargs * sizeof(bool));
		for (i = 0; i < function.nvargs; i++)
		{
			if (function.args[nfixedarg + i] == NULL)
				nulls[i] = true;
			else
			{
				elems[i] = OidInputFunctionCall(func,
								(char *) function.args[nfixedarg + i], elmioparam, -1);
				pfree(function.args[nfixedarg + i]);
			}
		}

		dims[0] = function.nvargs;
		lbs[0] = 1;
		arry = construct_md_array(elems, nulls, 1, dims, lbs, element_type,
								  elmlen, elmbyval, elmalign);
		self->fcinfo.arg[nfixedarg] = PointerGetDatum(arry);
	}

	/*
	 * assign default arguments
	 */
	if (function.ndargs > 0)
	{
		Datum		proargdefaults;
		bool		isnull;
		char	   *str;
		List	   *defaults;
		int			ndelete;
		ListCell   *l;

		/* shouldn't happen, FuncnameGetCandidates messed up */
		if (function.ndargs > pp->pronargdefaults)
			elog(ERROR, "not enough default arguments");

		proargdefaults = SysCacheGetAttr(PROCOID, ftup,
										 Anum_pg_proc_proargdefaults,
										 &isnull);
		Assert(!isnull);
		str = TextDatumGetCString(proargdefaults);
		defaults = (List *) stringToNode(str);
		Assert(IsA(defaults, List));
		pfree(str);
		/* Delete any unused defaults from the returned list */
		ndelete = list_length(defaults) - function.ndargs;
		while (ndelete-- > 0)
			defaults = list_delete_first(defaults);

		self->arg_econtext = CreateStandaloneExprContext();
		foreach(l, defaults)
		{
			Expr	   *expr = (Expr *) lfirst(l);
			ExprState  *argstate;
			ExprDoneCond thisArgIsDone;

			/* probably shouldn't happen ... */
			if (nargs >= FUNC_MAX_ARGS)
				ereport(ERROR,
						(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
				 errmsg("cannot pass more than %d arguments to a function", FUNC_MAX_ARGS)));

			argstate = ExecInitExpr(expr, NULL);

			self->fcinfo.arg[nargs] = ExecEvalExpr(argstate,
												   self->arg_econtext,
												   &self->fcinfo.argnull[nargs],
												   &thisArgIsDone);

			if (thisArgIsDone != ExprSingleResult)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("functions and operators can take at most one set argument")));

			nargs++;
		}
Exemplo n.º 18
0
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);
}
Exemplo n.º 19
0
Datum
pseudoinverse(PG_FUNCTION_ARGS)
{
    /*
     * A note on types: PostgreSQL array dimensions are of type int. See, e.g.,
     * the macro definition ARR_DIMS
     */
    int         rows, columns;
    float8     *A, *Aplus;
    ArrayType  *A_PG, *Aplus_PG;
    int lbs[2], dims[2];

    /*
     * Perform all the error checking needed to ensure that no one is
     * trying to call this in some sort of crazy way.
     */
    if (PG_NARGS() != 1)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("pseudoinverse called with %d arguments",
                        PG_NARGS())));
    }
    if (PG_ARGISNULL(0))
        PG_RETURN_NULL();

    A_PG = PG_GETARG_ARRAYTYPE_P(0);

    if (ARR_ELEMTYPE(A_PG) != FLOAT8OID)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("pseudoinverse only defined over float8[]")));
    if (ARR_NDIM(A_PG) != 2)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("pseudoinverse only defined over 2 dimensional arrays"))
               );
    if (ARR_NULLBITMAP(A_PG))
        ereport(ERROR,
                (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
                 errmsg("null array element not allowed in this context")));

    /* Extract rows, columns, and data */
    rows = ARR_DIMS(A_PG)[0];
    columns = ARR_DIMS(A_PG)[1];
    A = (float8 *) ARR_DATA_PTR(A_PG);


    /*  Allocate a PG array for the result, "Aplus" is A+, the pseudo inverse of A */
    lbs[0] = 1;
    lbs[1] = 1;
    dims[0] = columns;
    dims[1] = rows;
    Aplus_PG = construct_md_array(NULL, NULL, 2, dims, lbs, FLOAT8OID,
                                  sizeof(float8), true, 'd');

    Aplus = (float8 *) ARR_DATA_PTR(Aplus_PG);

    pinv(rows,columns,A,Aplus);

    PG_RETURN_ARRAYTYPE_P(Aplus_PG);
}
Datum array_multi_index( PG_FUNCTION_ARGS ) {
	if( PG_ARGISNULL(0) ) {
		PG_RETURN_NULL();
	}
	if( PG_ARGISNULL(1) ) {
		PG_RETURN_NULL();
	}
	
	ArrayType* values = PG_GETARG_ARRAYTYPE_P( 0 );
	ArrayType* indices = PG_GETARG_ARRAYTYPE_P( 1 );

	Oid values_type = ARR_ELEMTYPE( values );
	int16 values_width;
	bool values_passbyvalue;
	char values_alignmentcode;
	Datum* values_content;
	bool* values_nullflags;
	int values_length;
	get_typlenbyvalalign( values_type, &values_width, &values_passbyvalue, &values_alignmentcode );
	deconstruct_array( values, values_type, values_width, values_passbyvalue, values_alignmentcode, &values_content, &values_nullflags, &values_length );

	Oid indices_type = ARR_ELEMTYPE( indices );
	int16 indices_width;
	bool indices_passbyvalue;
	char indices_alignmentcode;
	Datum* indices_content;
	bool* indices_nullflags;
	int indices_length;
	get_typlenbyvalalign( indices_type, &indices_width, &indices_passbyvalue, &indices_alignmentcode );
	deconstruct_array( indices, indices_type, indices_width, indices_passbyvalue, indices_alignmentcode, &indices_content, &indices_nullflags, &indices_length );
	
	Oid results_type = values_type;
	int16 results_width = values_width;
	bool results_passbyvalue = values_passbyvalue;
	char results_alignmentcode = values_alignmentcode;
	Datum* results_content = (Datum *)palloc( sizeof(Datum) * indices_length );
	bool* results_nullflags = (bool *)palloc0( sizeof(bool) * indices_length );
	int results_length = indices_length;
	int i;
	for( i = 0; i < indices_length; ++i ) {
		if( indices_nullflags[i] ) {
			results_content[i] = 0;
			results_nullflags[i] = true;
		} else if( indices_content[i] - 1 >= (long unsigned)values_length ) {
			results_content[i] = 0;
			results_nullflags[i] = true;
		} else {
			results_content[i] = values_content[ indices_content[i] - 1 ];
			results_nullflags[i] = values_nullflags[ indices_content[i] - 1 ];
		}
	}

	int dims[1];
	int lbs[1];
	dims[0] = results_length;
	lbs[0] = 1;
	ArrayType* results = construct_md_array( results_content, results_nullflags, 1, dims, lbs, results_type, results_width, results_passbyvalue, results_alignmentcode );
	pfree( results_content );
	pfree( results_nullflags );
	PG_RETURN_ARRAYTYPE_P( results ); 
}
Exemplo n.º 21
0
/*
 * Convert Python sequence to SQL array.
 */
static Datum
PLySequence_ToArray(PLyObToDatum *arg, PyObject *plrv,
					bool *isnull, bool inarray)
{
	ArrayType  *array;
	int			i;
	Datum	   *elems;
	bool	   *nulls;
	int64		len;
	int			ndim;
	int			dims[MAXDIM];
	int			lbs[MAXDIM];
	int			currelem;
	PyObject   *pyptr = plrv;
	PyObject   *next;

	if (plrv == Py_None)
	{
		*isnull = true;
		return (Datum) 0;
	}
	*isnull = false;

	/*
	 * Determine the number of dimensions, and their sizes.
	 */
	ndim = 0;
	len = 1;

	Py_INCREF(plrv);

	for (;;)
	{
		if (!PyList_Check(pyptr))
			break;

		if (ndim == MAXDIM)
			PLy_elog(ERROR, "number of array dimensions exceeds the maximum allowed (%d)", MAXDIM);

		dims[ndim] = PySequence_Length(pyptr);
		if (dims[ndim] < 0)
			PLy_elog(ERROR, "could not determine sequence length for function return value");

		if (dims[ndim] > MaxAllocSize)
			PLy_elog(ERROR, "array size exceeds the maximum allowed");

		len *= dims[ndim];
		if (len > MaxAllocSize)
			PLy_elog(ERROR, "array size exceeds the maximum allowed");

		if (dims[ndim] == 0)
		{
			/* empty sequence */
			break;
		}

		ndim++;

		next = PySequence_GetItem(pyptr, 0);
		Py_XDECREF(pyptr);
		pyptr = next;
	}
	Py_XDECREF(pyptr);

	/*
	 * Check for zero dimensions. This happens if the object is a tuple or a
	 * string, rather than a list, or is not a sequence at all. We don't map
	 * tuples or strings to arrays in general, but in the first level, be
	 * lenient, for historical reasons. So if the object is a sequence of any
	 * kind, treat it as a one-dimensional array.
	 */
	if (ndim == 0)
	{
		if (!PySequence_Check(plrv))
			PLy_elog(ERROR, "return value of function with array return type is not a Python sequence");

		ndim = 1;
		len = dims[0] = PySequence_Length(plrv);
	}

	/*
	 * Traverse the Python lists, in depth-first order, and collect all the
	 * elements at the bottom level into 'elems'/'nulls' arrays.
	 */
	elems = palloc(sizeof(Datum) * len);
	nulls = palloc(sizeof(bool) * len);
	currelem = 0;
	PLySequence_ToArray_recurse(arg->u.array.elm, plrv,
								dims, ndim, 0,
								elems, nulls, &currelem);

	for (i = 0; i < ndim; i++)
		lbs[i] = 1;

	array = construct_md_array(elems,
							   nulls,
							   ndim,
							   dims,
							   lbs,
							   arg->u.array.elmbasetype,
							   arg->u.array.elm->typlen,
							   arg->u.array.elm->typbyval,
							   arg->u.array.elm->typalign);

	return PointerGetDatum(array);
}
Exemplo n.º 22
0
/*
 * used by text_to_array() in varlena.c
 */
ArrayType *
create_singleton_array(FunctionCallInfo fcinfo,
					   Oid element_type,
					   Datum element,
					   int ndims)
{
	Datum		dvalues[1];
	int16		typlen;
	bool		typbyval;
	char		typalign;
	int			dims[MAXDIM];
	int			lbs[MAXDIM];
	int			i;
	ArrayMetaState *my_extra;

	if (ndims < 1)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid number of dimensions: %d", ndims)));
	if (ndims > MAXDIM)
		ereport(ERROR,
				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
				 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
						ndims, MAXDIM)));

	dvalues[0] = element;

	for (i = 0; i < ndims; i++)
	{
		dims[i] = 1;
		lbs[i] = 1;
	}

	/*
	 * We arrange to look up info about element type 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 */
		get_typlenbyvalalign(element_type,
							 &my_extra->typlen,
							 &my_extra->typbyval,
							 &my_extra->typalign);
		my_extra->element_type = element_type;
	}
	typlen = my_extra->typlen;
	typbyval = my_extra->typbyval;
	typalign = my_extra->typalign;

	return construct_md_array(dvalues, NULL, ndims, dims, lbs, element_type,
							  typlen, typbyval, typalign);
}
Exemplo n.º 23
0
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);
}