Beispiel #1
0
Int4
pgtype_desclength(StatementClass *stmt, OID type, int col, int handle_unknown_size_as)
{
	switch (type)
	{
		case PG_TYPE_INT2:
			return 2;

		case PG_TYPE_OID:
		case PG_TYPE_XID:
		case PG_TYPE_INT4:
			return 4;

		case PG_TYPE_INT8:
			return 20;			/* signed: 19 digits + sign */

		case PG_TYPE_NUMERIC:
			return getNumericColumnSize(stmt, type, col) + 2;

		case PG_TYPE_FLOAT4:
		case PG_TYPE_MONEY:
			return 4;

		case PG_TYPE_FLOAT8:
			return 8;

		case PG_TYPE_DATE:
		case PG_TYPE_TIME:
		case PG_TYPE_ABSTIME:
		case PG_TYPE_DATETIME:
		case PG_TYPE_TIMESTAMP_NO_TMZONE:
		case PG_TYPE_TIMESTAMP:
		case PG_TYPE_VARCHAR:
		case PG_TYPE_BPCHAR:
			return pgtype_column_size(stmt, type, col, handle_unknown_size_as);
		default:
			return pgtype_column_size(stmt, type, col, handle_unknown_size_as);
	}
}
Beispiel #2
0
Int4
pgtype_display_size(StatementClass *stmt, OID type, int col, int handle_unknown_size_as)
{
	int	dsize;

	switch (type)
	{
		case PG_TYPE_INT2:
			return 6;

		case PG_TYPE_OID:
		case PG_TYPE_XID:
			return 10;

		case PG_TYPE_INT4:
			return 11;

		case PG_TYPE_INT8:
			return 20;			/* signed: 19 digits + sign */

		case PG_TYPE_NUMERIC:
			dsize = getNumericColumnSize(stmt, type, col);
			return dsize < 0 ? dsize : dsize + 2;

		case PG_TYPE_MONEY:
			return 15;			/* ($9,999,999.99) */

		case PG_TYPE_FLOAT4:
			return 13;

		case PG_TYPE_FLOAT8:
			return 22;

#if (ODBCVER >= 0x0350)
		case PG_TYPE_UUID:
			return 36;
#endif /* ODBCVER */

			/* Character types use regular precision */
		default:
			return pgtype_column_size(stmt, type, col, handle_unknown_size_as);
	}
}
Beispiel #3
0
/*
 *	Transfer octet length.
 */
Int4
pgtype_transfer_octet_length(StatementClass *stmt, OID type, int col, int handle_unknown_size_as)
{
	ConnectionClass	*conn = SC_get_conn(stmt);

	int	coef = 1;
	Int4	prec = pgtype_column_size(stmt, type, col, handle_unknown_size_as), maxvarc;
	switch (type)
	{
		case PG_TYPE_VARCHAR:
		case PG_TYPE_BPCHAR:
		case PG_TYPE_TEXT:
			if (SQL_NO_TOTAL == prec)
				return prec;
#ifdef	UNICODE_SUPPORT
			if (CC_is_in_unicode_driver(conn))
				return prec * WCLEN;
#endif /* UNICODE_SUPPORT */
			/* after 7.2 */
			if (PG_VERSION_GE(conn, 7.2))
				coef = conn->mb_maxbyte_per_char;
			if (coef < 2 && (conn->connInfo).lf_conversion)
				/* CR -> CR/LF */
				coef = 2;
			if (coef == 1)
				return prec;
			maxvarc = conn->connInfo.drivers.max_varchar_size;
			if (prec <= maxvarc && prec * coef > maxvarc)
				return maxvarc;
			return coef * prec;
		case PG_TYPE_BYTEA:
			return prec;
		default:
			if (type == conn->lobj_type)
				return prec;
	}
	return -1;
}
Beispiel #4
0
/*
 *	The length in bytes of data transferred on an SQLGetData, SQLFetch,
 *	or SQLFetchScroll operation if SQL_C_DEFAULT is specified.
 */
Int4
pgtype_buffer_length(StatementClass *stmt, OID type, int col, int handle_unknown_size_as)
{
	ConnectionClass	*conn = SC_get_conn(stmt);

	switch (type)
	{
		case PG_TYPE_INT2:
			return 2; /* sizeof(SQLSMALLINT) */

		case PG_TYPE_OID:
		case PG_TYPE_XID:
		case PG_TYPE_INT4:
			return 4; /* sizeof(SQLINTEGER) */

		case PG_TYPE_INT8:
			if (SQL_C_CHAR == pgtype_to_ctype(stmt, type))
				return 20;			/* signed: 19 digits + sign */
			return 8; /* sizeof(SQLSBININT) */

		case PG_TYPE_NUMERIC:
			return getNumericColumnSize(stmt, type, col) + 2;

		case PG_TYPE_FLOAT4:
		case PG_TYPE_MONEY:
			return 4; /* sizeof(SQLREAL) */

		case PG_TYPE_FLOAT8:
			return 8; /* sizeof(SQLFLOAT) */

		case PG_TYPE_DATE:
		case PG_TYPE_TIME:
			return 6;		/* sizeof(DATE(TIME)_STRUCT) */

		case PG_TYPE_ABSTIME:
		case PG_TYPE_DATETIME:
		case PG_TYPE_TIMESTAMP:
		case PG_TYPE_TIMESTAMP_NO_TMZONE:
			return 16;		/* sizeof(TIMESTAMP_STRUCT) */

		case PG_TYPE_UUID:
			return 16;		/* sizeof(SQLGUID) */

			/* Character types use the default precision */
		case PG_TYPE_VARCHAR:
		case PG_TYPE_BPCHAR:
			{
			int	coef = 1;
			Int4	prec = pgtype_column_size(stmt, type, col, handle_unknown_size_as), maxvarc;
			if (SQL_NO_TOTAL == prec)
				return prec;
#ifdef	UNICODE_SUPPORT
			if (CC_is_in_unicode_driver(conn))
				return prec * WCLEN;
#endif /* UNICODE_SUPPORT */
			/* after 7.2 */
			if (PG_VERSION_GE(conn, 7.2))
				coef = conn->mb_maxbyte_per_char;
			if (coef < 2 && (conn->connInfo).lf_conversion)
				/* CR -> CR/LF */
				coef = 2;
			if (coef == 1)
				return prec;
			maxvarc = conn->connInfo.drivers.max_varchar_size;
			if (prec <= maxvarc && prec * coef > maxvarc)
				return maxvarc;
			return coef * prec;
			}
		default:
			return pgtype_column_size(stmt, type, col, handle_unknown_size_as);
	}
}
Beispiel #5
0
/*
 *	Returns the description of a parameter marker.
 *	This function is listed as not being supported by SQLGetFunctions() because it is
 *	used to describe "parameter markers" (not bound parameters), in which case,
 *	the dbms should return info on the markers.  Since Postgres doesn't support that,
 *	it is best to say this function is not supported and let the application assume a
 *	data type (most likely varchar).
 */
RETCODE		SQL_API
PGAPI_DescribeParam(HSTMT hstmt,
					SQLUSMALLINT ipar,
					SQLSMALLINT FAR * pfSqlType,
					SQLULEN FAR * pcbParamDef,
					SQLSMALLINT FAR * pibScale,
					SQLSMALLINT FAR * pfNullable)
{
	StatementClass *stmt = (StatementClass *) hstmt;
	CSTR func = "PGAPI_DescribeParam";
	IPDFields	*ipdopts;
	RETCODE		ret = SQL_SUCCESS;
	int		num_params;
	OID		pgtype;

	mylog("%s: entering...%d\n", func, ipar);

	if (!stmt)
	{
		SC_log_error(func, "", NULL);
		return SQL_INVALID_HANDLE;
	}
	SC_clear_error(stmt);

	ipdopts = SC_get_IPDF(stmt);
	/*if ((ipar < 1) || (ipar > ipdopts->allocated))*/
	num_params = stmt->num_params;
	if (num_params < 0)
	{
		SQLSMALLINT	num_p;

		PGAPI_NumParams(stmt, &num_p);
		num_params = num_p;
	}
	if ((ipar < 1) || (ipar > num_params))
	{
inolog("num_params=%d\n", stmt->num_params);
		SC_set_error(stmt, STMT_BAD_PARAMETER_NUMBER_ERROR, "Invalid parameter number for PGAPI_DescribeParam.", func);
		return SQL_ERROR;
	}
	extend_iparameter_bindings(ipdopts, stmt->num_params);

#define	return	DONT_CALL_RETURN_FROM_HERE???
	/* StartRollbackState(stmt); */
	if (NOT_YET_PREPARED == stmt->prepared)
	{
		decideHowToPrepare(stmt, FALSE);
inolog("howTo=%d\n", SC_get_prepare_method(stmt));
		switch (SC_get_prepare_method(stmt))
		{
			case NAMED_PARSE_REQUEST:
			case PARSE_TO_EXEC_ONCE:
			case PARSE_REQ_FOR_INFO:
				if (ret = prepareParameters(stmt), SQL_ERROR == ret)
					goto cleanup;
		}
	}

	ipar--;
	pgtype = PIC_get_pgtype(ipdopts->parameters[ipar]);
	/*
	 * This implementation is not very good, since it is supposed to
	 * describe
	 */
	/* parameter markers, not bound parameters.  */
	if (pfSqlType)
	{
inolog("[%d].SQLType=%d .PGType=%d\n", ipar, ipdopts->parameters[ipar].SQLType, pgtype);
		if (ipdopts->parameters[ipar].SQLType)
			*pfSqlType = ipdopts->parameters[ipar].SQLType;
		else if (pgtype)
			*pfSqlType = pgtype_to_concise_type(stmt, pgtype, PG_STATIC);
		else
		{
			ret = SQL_ERROR;
			SC_set_error(stmt, STMT_EXEC_ERROR, "Unfortunatley couldn't get this paramater's info", func);
			goto cleanup;
		}
	}

	if (pcbParamDef)
	{
		*pcbParamDef = 0;
		if (ipdopts->parameters[ipar].SQLType)
			*pcbParamDef = ipdopts->parameters[ipar].column_size;
		if (0 == *pcbParamDef && pgtype)
			*pcbParamDef = pgtype_column_size(stmt, pgtype, PG_STATIC, PG_STATIC);
	}

	if (pibScale)
	{
		*pibScale = 0;
		if (ipdopts->parameters[ipar].SQLType)
			*pibScale = ipdopts->parameters[ipar].decimal_digits;
		else if (pgtype)
			*pibScale = pgtype_scale(stmt, pgtype, -1);
	}

	if (pfNullable)
		*pfNullable = pgtype_nullable(SC_get_conn(stmt), ipdopts->parameters[ipar].paramType);
cleanup:
#undef	return
	if (stmt->internal)
		ret = DiscardStatementSvp(stmt, ret, FALSE);
	return ret;
}