Exemple #1
0
int
pqt_get_lseg(PGtypeArgs *args)
{
    DECLVALUE(args);
    unsigned int *v;
    PGlseg *lseg = va_arg(args->ap, PGlseg *);

    CHKGETVALS(args, lseg);

    if (args->format == TEXTFMT)
    {
        PGpoint *pts = (PGpoint *)lseg;

        if (*value++ != '[' ||
                !text2point(pts, value, &value) ||
                *value++ != ',' ||
                !text2point(pts + 1, value, &value) ||
                *value != ']')
            RERR_STR2INT(args);

        return 0;
    }

    v = (unsigned int *) value;
    pqt_swap8(&lseg->pts[0].x, v, 0);
    pqt_swap8(&lseg->pts[0].y, v + 2, 0);
    pqt_swap8(&lseg->pts[1].x, v + 4, 0);
    pqt_swap8(&lseg->pts[1].y, v + 6, 0);
    return 0;
}
Exemple #2
0
int
pqt_get_circle(PGtypeArgs *args)
{
    DECLVALUE(args);
    unsigned int *v;
    PGcircle *circle = va_arg(args->ap, PGcircle *);

    CHKGETVALS(args, circle);

    if (args->format == TEXTFMT)
    {
        if (*value++ != '<' ||
                !text2point((PGpoint *)circle, value, &value) ||
                *value++ != ',' ||
                !pqt_text_to_float8(&circle->radius, value, &value) ||
                *value != '>')
            RERR_STR2INT(args);

        return 0;
    }

    v = (unsigned int *) value;
    pqt_swap8(&circle->center.x, v, 0);
    pqt_swap8(&circle->center.y, v + 2, 0);
    pqt_swap8(&circle->radius,   v + 4, 0);
    return 0;
}
Exemple #3
0
int
pqt_get_box(PGtypeArgs *args)
{
    DECLVALUE(args);
    unsigned int *v;
    PGbox *box = va_arg(args->ap, PGbox *);

    CHKGETVALS(args, box);

    if (args->format == TEXTFMT)
    {
        PGpoint *pts = (PGpoint *)box;

        if (!text2point(pts, value, &value) ||
                *value++ != ',' ||
                !text2point(pts + 1, value, NULL))
            RERR_STR2INT(args);

        return 0;
    }

    v = (unsigned int *) value;
    pqt_swap8(&box->high.x, v, 0);
    pqt_swap8(&box->high.y, v + 2, 0);
    pqt_swap8(&box->low.x,  v + 4, 0);
    pqt_swap8(&box->low.y,  v + 6, 0);
    return 0;
}
Exemple #4
0
int
pqt_get_point(PGtypeArgs *args)
{
    DECLVALUE(args);
    PGpoint *pt = va_arg(args->ap, PGpoint *);

    CHKGETVALS(args, pt);

    if (args->format == TEXTFMT)
    {
        if (!text2point(pt, value, NULL))
            RERR_STR2INT(args);

        return 0;
    }

    pqt_swap8(&pt->x, (unsigned int *) value, 0);
    pqt_swap8(&pt->y, ((unsigned int *) (value)) + 2, 0);
    return 0;
}
Exemple #5
0
int
pqt_get_array(PGtypeArgs *args)
{
    int i,t;
    int vlen;
    int ntups;
    int nattrs;
    Oid elemoid;
    DECLVALUE(args);
    PGresult *res;
    int first_tup;
    PGarray *arr = va_arg(args->ap, PGarray *);

    CHKGETVALS(args, arr);

    if (args->format == TEXTFMT)
        return args->errorf(args, "array does not support text results");

    /* number of dims */
    arr->ndims = pqt_buf_getint4(value);
    value += 4;

    /* skip NULL flag */
    value += 4;

    /* check the element oid */
    elemoid = (Oid)pqt_buf_getint4(value);
    if (elemoid != args->typhandler->typoid)
        return args->errorf(args,
                            "array element type %u is different than what server says %u",
                            args->typhandler->typoid, elemoid);
    value += 4;

    /* arr dims and lbounds */
    first_tup = 1;
    for (i=0, ntups=1; i < arr->ndims; i++)
    {
        arr->dims[i] = pqt_buf_getint4(value);
        value += 4;

        arr->lbound[i] = pqt_buf_getint4(value);
        value += 4;

        ntups *= arr->dims[i];
    }

    /* This means ndims is zero because the above loop never iterated. */
    if (i == 0)
        ntups = 0;

    /* numTuples is the number of array items
     * and numAttributes is 1 for non-composites.
     */
    nattrs = (args->typhandler->nattrs > 0) ? args->typhandler->nattrs : 1;

    if (!(res = pqt_copyresult(args, nattrs)))
        RERR_MEM(args);

    for (t=0; t < ntups; t++)
    {
        /* get the value len */
        vlen = pqt_buf_getint4(value);
        value += 4;

        /* Regular Array with 1 attr per tuple */
        if (args->typhandler->nattrs == 0)
        {
            /* set the field value */
            if (!PQsetvalue(res, t, 0, value, vlen))
            {
                PQclear(res);
                return -1;
            }

            if (vlen > 0)
                value += vlen;

            continue;
        }

        /* ------------------------
         * COMPOSITE/RECORD
         */

        /* NULL compsoite array item, fill in attrs with NULL */
        if (vlen == NULL_LEN)
        {
            int x;

            for (x=0; x < nattrs; x++)
            {
                if (!PQsetvalue(res, t, x, NULL, NULL_LEN))
                {
                    PQclear(res);
                    return -1;
                }
            }

            /* move on to next tuple, done here. */
            continue;
        }

        /* verify that server's attr count matches ours */
        if (first_tup)
        {
            int attcnt = pqt_buf_getint4(value);

            /* watch for invalidation issues */
            if (attcnt != nattrs)
            {
                PQclear(res);
                return args->errorf(args,
                                    "type handler attribute count is %d but server says it's %d",
                                    args->typhandler->nattrs, attcnt);
            }
        }

        /* skip attr count */
        value += 4;

        /* composite attributes (record columns) */
        for (i=0; i < nattrs; i++)
        {
            /* watch for invalidation issues */
            if (first_tup &&
                    (Oid) pqt_buf_getint4(value) != args->typhandler->attDescs[i].attoid)
            {
                Oid server_oid = (Oid) pqt_buf_getint4(value);

                args->errorf(args,
                             "type handler attribute OID is %u but server says it's %u",
                             args->typhandler->attDescs[i].attoid, server_oid);

                PQclear(res);
                return -1;
            }

            /* skip oid */
            value += 4;

            /* get the value length */
            vlen = pqt_buf_getint4(value);
            value += 4;

            /* set the field value */
            if (!PQsetvalue(res, t, i, value, vlen))
            {
                PQclear(res);
                return -1;
            }

            if (vlen > 0)
                value += vlen;
        }

        first_tup = 0;
    }

    arr->res = res;
    return 0;
}
Exemple #6
0
static int
get_inet2(PGtypeArgs *args, int is_cidr)
{
	DECLVALUE(args);
	unsigned short family;
	PGinet *inet = va_arg(args->ap, PGinet *);

	CHKGETVALS(args, inet);

	if (args->format == TEXTFMT)
	{
		int r;
		char *p;
		char ipstr[80];
		struct addrinfo *ai = NULL;
		struct addrinfo hints;

		pqt_strcpy(ipstr, sizeof(ipstr), value);
		if ((p = strrchr(ipstr, '/')))
		{
			*p = 0;
			inet->mask = atoi(p+1);
		}
		else
		{
			inet->mask = 32;
		}

		inet->is_cidr = is_cidr;

		/* suppress hostname lookups */
		memset(&hints, 0, sizeof(hints));
		hints.ai_flags = AI_NUMERICHOST;

		/* Without this, windows chokes with WSAHOST_NOT_FOUND */
#ifdef PQT_WIN32
		hints.ai_family = AF_INET;
#endif

		if ((r = getaddrinfo(ipstr, NULL, &hints, &ai)) || !ai)
		{
			if(r == EAI_BADFLAGS)
			{
				hints.ai_flags = 0;
				r = getaddrinfo(ipstr, NULL, &hints, &ai);
			}
			/* Another WSAHOST_NOT_FOUND work around, but for IPv6 */
#if defined(PQT_WIN32) && defined(AF_INET6)
			else if(r == WSAHOST_NOT_FOUND)
			{
				hints.ai_flags = 0;
				hints.ai_family = AF_INET6;
				r = getaddrinfo(ipstr, NULL, &hints, &ai);
			}
#endif

			if(r)
				RERR_STR2INT(args);
		}

		inet->sa_buf_len = (int) ai->ai_addrlen;
		memcpy(inet->sa_buf, ai->ai_addr, inet->sa_buf_len);

		/* Some platforms, lika AIX 4.3, do not zero this structure properly.
     * The family and port are dirty, so set the first 4 bytes to 0 and
     * then re-set the family.  I saw "0x1002" as the first 2 bytes of
     * this structure (dumb getaddrinfo), it should be "0x0002" for AF_INET.
     */
		memset(inet->sa_buf, 0, 4);
		((struct sockaddr *)inet->sa_buf)->sa_family = ai->ai_addr->sa_family;

		/* Uninitialized memory, postgres inet/cidr types don't store this.
     * Make sure its set to 0.  Another AIX problem (maybe other platforms).
		 */
#ifdef AF_INET6
		if (ai->ai_addr->sa_family == AF_INET6)
			((struct sockaddr_in6 *)inet->sa_buf)->sin6_flowinfo = 0;
#endif

		freeaddrinfo(ai);
		return 0;
	}

	family = (unsigned short) *value++;
	if (family == PGSQL_AF_INET)
	{
		struct sockaddr_in *sa = (struct sockaddr_in *) inet->sa_buf;
		sa->sin_family = AF_INET;
		inet->mask = (unsigned char) *value++;
		inet->is_cidr = *value++;
		memcpy(&sa->sin_addr, value + 1, *value);
		inet->sa_buf_len = (int) sizeof(struct sockaddr_in);
	}
#ifdef AF_INET6
	else if (family == PGSQL_AF_INET6)
	{
		struct sockaddr_in6 *sa = (struct sockaddr_in6 *) inet->sa_buf;
		sa->sin6_family = AF_INET6;
		inet->mask = (unsigned char) *value++;
		inet->is_cidr = *value++;
		memcpy(&sa->sin6_addr, value + 1, *value);
		inet->sa_buf_len = (int) sizeof(struct sockaddr_in6);
	}
#endif
	else
	{
		return args->errorf(args, "Unknown inet address family %d", family);
	}

	return 0;
}