Beispiel #1
0
Datum
pgx_complex_divide(PG_FUNCTION_ARGS) {
    TupleDesc tupdesc;
    HeapTuple tuple;
    double re[2];
    double im[2];
    int i;
    double q;
    Datum datum[2];
    bool isnull[2];
 
    // build a tuple descriptor for our result type 
    if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
        ereport(ERROR,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                 errmsg("function returning record called in context "
                        "that cannot accept type record")));

    // unwrap values.    
    for (i = 0; i < 2; i++) {
        HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(i);
        bool isnull[2];
        Datum dr, di;

        dr = GetAttributeByName(t, "re", &isnull[0]);
        di = GetAttributeByName(t, "im", &isnull[1]);

        // STRICT prevents the 'complex' value from being null but does
        // not prevent its components from being null.        
        if (isnull[0] || isnull[1]) {
            PG_RETURN_NULL();
        }
        
        re[i] = DatumGetFloat8(dr);
        im[i] = DatumGetFloat8(di);
    }

    // the denominator is the square of the magnitude of the divisor.
    q = re[1] * re[1] + im[1] * im[1];
    
    // should I throw error instead of returning null?
    if (q == 0.0) {
        PG_RETURN_NULL();
    }

    datum[0] = Float8GetDatum((re[0] * re[1] + im[0] * im[1]) / q);
    datum[1] = Float8GetDatum((im[0] * re[1] - im[1] * re[0]) / q);

    BlessTupleDesc(tupdesc);
    tuple = heap_form_tuple(tupdesc, datum, isnull);
 
    PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
}
Beispiel #2
0
Datum
pgx_complex_norm(PG_FUNCTION_ARGS) {
    HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
    TupleDesc tupdesc;
    HeapTuple tuple;
    double re;
    double im;
    bool isnull[2];
    Datum datum[2];
    double m;
 
    // build a tuple descriptor for our result type 
    if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
        ereport(ERROR,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                 errmsg("function returning record called in context "
                        "that cannot accept type record")));
        
    // unwrap values.    
    datum[0] = GetAttributeByName(t, "re", &isnull[0]);
    datum[1] = GetAttributeByName(t, "im", &isnull[1]);

    // STRICT prevents the 'complex' value from being null but does
    // not prevent its components from being null.        
    if (isnull[0] || isnull[1]) {
        PG_RETURN_NULL();
    }
        
    re = DatumGetFloat8(datum[0]);
    im = DatumGetFloat8(datum[1]);

    m = hypot(re, im);
   
    // should I throw error instead of returning null?
    if (m == 0.0) {
        PG_RETURN_NULL();
    } 

    datum[0] = Float8GetDatum(re / m);
    datum[1] = Float8GetDatum(im / m);

    BlessTupleDesc(tupdesc);
    tuple = heap_form_tuple(tupdesc, datum, isnull);
 
    PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
}
Beispiel #3
0
Datum
overpaid(PG_FUNCTION_ARGS)
{
	HeapTupleHeader tuple = PG_GETARG_HEAPTUPLEHEADER(0);
	bool		isnull;
	int32		salary;

	salary = DatumGetInt32(GetAttributeByName(tuple, "salary", &isnull));
	if (isnull)
		PG_RETURN_NULL();
	PG_RETURN_BOOL(salary > 699);
}
Beispiel #4
0
bool
c_overpaid(TupleTableSlot *t,	/* the current instance of EMP */
		   int32 limit)
{
	bool		isnull;
	int32		salary;

	salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
	if (isnull)
		return (false);
	return salary > limit;
}
Beispiel #5
0
bool
c_overpaid(HeapTupleHeader t,	/* the current instance of EMP */
		   int32 limit)
{
	bool		isnull;
	int32		salary;

	salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
	if (isnull)
		return false;
	return salary > limit;
}
Beispiel #6
0
Datum
pgx_complex_near(PG_FUNCTION_ARGS) {
    double re[2];
    double im[2];
    double p, q;
    int i;

    // unwrap values.    
    for (i = 0; i < 2; i++) {
        HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(i);
        bool isnull[2];

        Datum dr = GetAttributeByName(t, "re", &isnull[0]);
        Datum di = GetAttributeByName(t, "im", &isnull[1]);

        // STRICT prevents the 'complex' value from being null but does
        // not prevent its components from being null.        
        if (isnull[0] || isnull[1]) {
            PG_RETURN_NULL();
        }
        
        re[i] = DatumGetFloat8(dr);
        im[i] = DatumGetFloat8(di);
    }

    // compute distance between points, distance of points from origin.
    p = hypot(re[0] - re[1], im[0] - im[1]);
    q = hypot(re[0], im[0]) + hypot(re[1], im[1]);
    
    if (q == 0) {
        PG_RETURN_BOOL(1);
    }
    
    // we consider the points 'near' each other if the distance between them is small
    // relative to the size of them. 
    PG_RETURN_BOOL(p / q < 1e-8); 
}
Beispiel #7
0
Datum
c_overpaid(PG_FUNCTION_ARGS)
{
	HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
	int32		limit = PG_GETARG_INT32(1);
	bool		isnull;
	int32		salary;

	salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
	if (isnull)
		PG_RETURN_BOOL(false);

	/*
	 * Alternatively, we might prefer to do PG_RETURN_NULL() for null salary
	 */

	PG_RETURN_BOOL(salary > limit);
}
Beispiel #8
0
Datum new_order(PG_FUNCTION_ARGS)
{
	/* Input variables. */
	int32 w_id = PG_GETARG_INT32(0);
	int32 d_id = PG_GETARG_INT32(1);
	int32 c_id = PG_GETARG_INT32(2);
	int32 o_all_local = PG_GETARG_INT32(3);
	int32 o_ol_cnt = PG_GETARG_INT32(4);

	TupleDesc tupdesc;
	SPITupleTable *tuptable;
	HeapTuple tuple;

	int32 ol_i_id[15];
	int32 ol_supply_w_id[15];
	int32 ol_quantity[15];

	int i, j;

	int ret;
	char query[1024];

	char *w_tax = NULL;

	char *d_tax = NULL;
	char *d_next_o_id = NULL;

	char *c_discount = NULL;
	char *c_last = NULL;
	char *c_credit = NULL;

	float order_amount = 0.0;

	char *i_price[15];
	char *i_name[15];
	char *i_data[15];

	float ol_amount[15];
	char *s_quantity[15];
	char *my_s_dist[15];
	char *s_data[15];

	/* Loop through the last set of parameters. */
	for (i = 0, j = 5; i < 15; i++) {
		bool isnull;
		HeapTupleHeader  t = PG_GETARG_HEAPTUPLEHEADER(j++);
		ol_i_id[i] = DatumGetInt32(GetAttributeByName(t, "ol_i_id", &isnull));
		ol_supply_w_id[i] = DatumGetInt32(GetAttributeByName(t,
				"ol_supply_w_id", &isnull));
		ol_quantity[i] = DatumGetInt32(GetAttributeByName(t, "ol_quantity",
				&isnull));
	}

	elog(DEBUG1, "%d w_id = %d", (int) getpid(), w_id);
	elog(DEBUG1, "%d d_id = %d", (int) getpid(), d_id);
	elog(DEBUG1, "%d c_id = %d", (int) getpid(), c_id);
	elog(DEBUG1, "%d o_all_local = %d", (int) getpid(), o_all_local);
	elog(DEBUG1, "%d o_ol_cnt = %d", (int) getpid(), o_ol_cnt);

	elog(DEBUG1, "%d ##  ol_i_id  ol_supply_w_id  ol_quantity",
		(int) getpid());
	elog(DEBUG1, "%d --  -------  --------------  -----------",
		(int) getpid());
	for (i = 0; i < o_ol_cnt; i++) {
		elog(DEBUG1, "%d %2d  %7d  %14d  %11d", (int) getpid(),
				i + 1, ol_i_id[i], ol_supply_w_id[i], ol_quantity[i]);
	}

	SPI_connect();

	sprintf(query, NEW_ORDER_1, w_id);

	elog(DEBUG1, "%d %s", (int) getpid(), query);

	ret = SPI_exec(query, 0);
	if (ret == SPI_OK_SELECT && SPI_processed > 0) {
		tupdesc = SPI_tuptable->tupdesc;
		tuptable = SPI_tuptable;
		tuple = tuptable->vals[0];

		w_tax = SPI_getvalue(tuple, tupdesc, 1);
		elog(DEBUG1, "%d w_tax = %s", (int) getpid(), w_tax);
	} else {
		elog(WARNING, "NEW_ORDER_1 failed");
		SPI_finish();
		PG_RETURN_INT32(10);
	}

	sprintf(query, NEW_ORDER_2, w_id, d_id);
	elog(DEBUG1, "%s", query);
	ret = SPI_exec(query, 0);
	if (ret == SPI_OK_SELECT && SPI_processed > 0) {
		tupdesc = SPI_tuptable->tupdesc;
		tuptable = SPI_tuptable;
		tuple = tuptable->vals[0];

		d_tax = SPI_getvalue(tuple, tupdesc, 1);
		d_next_o_id = SPI_getvalue(tuple, tupdesc, 2);
		elog(DEBUG1, "%d d_tax = %s", (int) getpid(), d_tax);
		elog(DEBUG1, "%d d_next_o_id = %s", (int) getpid(),
			d_next_o_id);
	} else {
		elog(WARNING, "NEW_ORDER_2 failed");
		SPI_finish();
		PG_RETURN_INT32(11);
	}

	sprintf(query, NEW_ORDER_3, w_id, d_id);
	elog(DEBUG1, "%d %s", (int) getpid(), query);
	ret = SPI_exec(query, 0);
	if (ret != SPI_OK_UPDATE) {
		elog(WARNING, "NEW_ORDER_3 failed");
		SPI_finish();
		PG_RETURN_INT32(12);
	}

	sprintf(query, NEW_ORDER_4, w_id, d_id, c_id);
	elog(DEBUG1, "%d %s", (int) getpid(), query);
	ret = SPI_exec(query, 0);
	if (ret == SPI_OK_SELECT && SPI_processed > 0) {
		tupdesc = SPI_tuptable->tupdesc;
		tuptable = SPI_tuptable;
		tuple = tuptable->vals[0];

		c_discount = SPI_getvalue(tuple, tupdesc, 1);
		c_last = SPI_getvalue(tuple, tupdesc, 2);
		c_credit = SPI_getvalue(tuple, tupdesc, 3);
		elog(DEBUG1, "%d c_discount = %s", (int) getpid(), c_discount);
		elog(DEBUG1, "%d c_last = %s", (int) getpid(), c_last);
		elog(DEBUG1, "%d c_credit = %s", (int) getpid(), c_credit);
	} else {
		elog(WARNING, "NEW_ORDER_4 failed");
		SPI_finish();
		PG_RETURN_INT32(13);
	}

	sprintf(query, NEW_ORDER_5, d_next_o_id, w_id, d_id);
	elog(DEBUG1, "%d %s", (int) getpid(), query);
	ret = SPI_exec(query, 0);
	if (ret != SPI_OK_INSERT) {
		elog(WARNING, "NEW_ORDER_5 failed %d", ret);
		SPI_finish();
		PG_RETURN_INT32(14);
	}

	sprintf(query, NEW_ORDER_6, d_next_o_id, d_id, w_id, c_id, o_ol_cnt,
		o_all_local);
	elog(DEBUG1, "%d %s", (int) getpid(), query);
	ret = SPI_exec(query, 0);
	if (ret != SPI_OK_INSERT) {
		elog(WARNING, "NEW_ORDER_6 failed");
		SPI_finish();
		PG_RETURN_INT32(15);
	}

	for (i = 0; i < o_ol_cnt; i++) {
		sprintf(query, NEW_ORDER_7, ol_i_id[i]);
		elog(DEBUG1, "%d %s", (int) getpid(), query);
		ret = SPI_exec(query, 0);
		/*
		 * Shouldn't have to check if ol_i_id is 0, but if the row
		 * doesn't exist, the query still passes.
		 */
		if (ol_i_id[i] != 0 && ret == SPI_OK_SELECT && SPI_processed > 0) {
			tupdesc = SPI_tuptable->tupdesc;
			tuptable = SPI_tuptable;
			tuple = tuptable->vals[0];

			i_price[i] = SPI_getvalue(tuple, tupdesc, 1);
			i_name[i] = SPI_getvalue(tuple, tupdesc, 2);
			i_data[i] = SPI_getvalue(tuple, tupdesc, 3);
			elog(DEBUG1, "%d i_price[%d] = %s", (int) getpid(), i,
				i_price[i]);
			elog(DEBUG1, "%d i_name[%d] = %s", (int) getpid(), i,
				i_name[i]);
			elog(DEBUG1, "%d i_data[%d] = %s", (int) getpid(), i,
				i_data[i]);
		} else {
			/* Item doesn't exist, rollback transaction. */
			SPI_finish();
			PG_RETURN_INT32(2);
		}

		ol_amount[i] = atof(i_price[i]) * (float) ol_quantity[i];
		sprintf(query, NEW_ORDER_8, s_dist[d_id - 1], ol_i_id[i], w_id);
		elog(DEBUG1, "%d %s", (int) getpid(), query);
		ret = SPI_exec(query, 0);
		if (ret == SPI_OK_SELECT && SPI_processed > 0) {
			tupdesc = SPI_tuptable->tupdesc;
			tuptable = SPI_tuptable;
			tuple = tuptable->vals[0];

			s_quantity[i] = SPI_getvalue(tuple, tupdesc, 1);
			my_s_dist[i] = SPI_getvalue(tuple, tupdesc, 2);
			s_data[i] = SPI_getvalue(tuple, tupdesc, 3);
			elog(DEBUG1, "%d s_quantity[%d] = %s", (int) getpid(),
				i, s_quantity[i]);
			elog(DEBUG1, "%d my_s_dist[%d] = %s", (int) getpid(),
				i, my_s_dist[i]);
			elog(DEBUG1, "%d s_data[%d] = %s", (int) getpid(), i,
				s_data[i]);
		} else {
			elog(WARNING, "NEW_ORDER_8 failed");
			SPI_finish();
			PG_RETURN_INT32(16);
		}
		order_amount += ol_amount[i];

		if (atoi(s_quantity[i]) > ol_quantity[i] + 10) {
			sprintf(query, NEW_ORDER_9, ol_quantity[i],
				ol_i_id[i], w_id);
		} else {
			sprintf(query, NEW_ORDER_9, ol_quantity[i] - 91,
				ol_i_id[i], w_id);
		}
		elog(DEBUG1, "%d %s", (int) getpid(), query);
		ret = SPI_exec(query, 0);
		if (ret != SPI_OK_UPDATE) {
			elog(WARNING, "NEW_ORDER_9 failed");
			SPI_finish();
			PG_RETURN_INT32(17);
		}

		sprintf(query, NEW_ORDER_10, d_next_o_id, d_id, w_id, i + 1,
			ol_i_id[i], ol_supply_w_id[i], ol_quantity[i],
			ol_amount[i], my_s_dist[i]);
		elog(DEBUG1, "%d %s", getpid(), query);
		ret = SPI_exec(query, 0);
		if (ret != SPI_OK_INSERT) {
			elog(WARNING, "NEW_ORDER_10 failed");
			SPI_finish();
			PG_RETURN_INT32(18);
		}
	}

	SPI_finish();
	PG_RETURN_INT32(0);
}