Skip to content

Commit

Permalink
Merge branch 'babelfish-for-postgresql:BABEL_3_X_DEV' into jira-babel…
Browse files Browse the repository at this point in the history
…-4008-2
  • Loading branch information
basasairohan authored Oct 20, 2023
2 parents eb8fe46 + 1f5e81e commit 42d99be
Show file tree
Hide file tree
Showing 32 changed files with 2,861 additions and 890 deletions.
16 changes: 3 additions & 13 deletions contrib/babelfishpg_common/sql/string_operators.sql
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
-- Wrap built-in CONCAT function to accept two text arguments.
-- This is necessary because CONCAT accepts arguments of type VARIADIC "any".
-- CONCAT also automatically handles NULL which || does not.
CREATE OR REPLACE FUNCTION sys.babelfish_concat_wrapper(leftarg text, rightarg text) RETURNS TEXT AS
$$
SELECT
CASE WHEN (current_setting('babelfishpg_tsql.concat_null_yields_null') = 'on') THEN
CASE
WHEN leftarg IS NULL OR rightarg IS NULL THEN NULL
ELSE CONCAT(leftarg, rightarg)
END
ELSE
CONCAT(leftarg, rightarg)
END
$$
LANGUAGE SQL STABLE;
CREATE OR REPLACE FUNCTION sys.babelfish_concat_wrapper(leftarg text, rightarg text) RETURNS TEXT
AS 'babelfishpg_tsql', 'babelfish_concat_wrapper'
LANGUAGE C STABLE PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.babelfish_concat_wrapper_outer(leftarg text, rightarg text) RETURNS sys.varchar(8000) AS
$$
Expand Down
88 changes: 51 additions & 37 deletions contrib/babelfishpg_tds/src/backend/tds/tdstypeio.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,10 @@ typedef struct FunctionCacheByTdsIdEntry
TdsIoFunctionData data;
} FunctionCacheByTdsIdEntry;

/*
/*
* This is a modified copy of a function from POSTGIS to get SRID from GSERIALIZED struct
*/
static int32_t
static int32_t
get_srid(uint8_t *id)
{
int32_t srid = 0;
Expand Down Expand Up @@ -242,9 +242,9 @@ getSendFunc(int funcId)
case TDS_SEND_DATETIMEOFFSET:
return TdsSendTypeDatetimeoffset;
case TDS_SEND_GEOMETRY:
return TdsSendTypeGeometry;
case TDS_SEND_GEOGRAPHY:
return TdsSendTypeGeography;
return TdsSendTypeGeometry;
case TDS_SEND_GEOGRAPHY:
return TdsSendTypeGeography;
/* TODO: should Assert here once all types are implemented */
default:
return NULL;
Expand Down Expand Up @@ -321,8 +321,8 @@ getRecvFunc(int funcId)
case TDS_RECV_DATETIMEOFFSET:
return TdsRecvTypeDatetimeoffset;
case TDS_RECV_GEOMETRY:
return TdsRecvTypeGeometry;
case TDS_RECV_GEOGRAPHY:
return TdsRecvTypeGeometry;
case TDS_RECV_GEOGRAPHY:
return TdsRecvTypeGeography;
/* TODO: should Assert here once all types are implemented */
default:
Expand Down Expand Up @@ -2014,7 +2014,7 @@ TdsRecvTypeDatetime2(const char *message, const ParameterToken token)
Datum
TdsRecvTypeGeometry(const char *message, const ParameterToken token)
{
Datum result = 0;
Datum result = 0;

/* Decode binary and convert if needed */
StringInfo buf = TdsGetStringInfoBufferFromToken(message, token);
Expand All @@ -2023,25 +2023,25 @@ TdsRecvTypeGeometry(const char *message, const ParameterToken token)

ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("Prepared Queries for Geometry DataType Currently not Supported in BabelFish")));
errmsg("Prepared Queries for Geometry DataType Currently not Supported in BabelFish")));

pfree(buf);
return result;
pfree(buf);
return result;
}

/* -------------------------------
* TdsRecvTypeGeography - converts external binary format to
* Geography data type
* Geography data type
* --------------------------------
*/
*/
/*
* It is a Placeholder Function for now
* TODO: Will need to address it in subsequent Code Changes
*/
Datum
TdsRecvTypeGeography(const char *message, const ParameterToken token)
{
Datum result = 0;
Datum result = 0;

/* Decode binary and convert if needed */
StringInfo buf = TdsGetStringInfoBufferFromToken(message, token);
Expand All @@ -2052,8 +2052,8 @@ TdsRecvTypeGeography(const char *message, const ParameterToken token)
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("Prepared Queries for Geography DataType Currently not Supported in BabelFish")));

pfree(buf);
return result;
pfree(buf);
return result;
}

static inline uint128
Expand Down Expand Up @@ -2426,8 +2426,8 @@ TdsRecvTypeTable(const char *message, const ParameterToken token)
case TDS_TYPE_SQLVARIANT:
values[i] = TdsTypeSqlVariantToDatum(temp);
break;
case TDS_TYPE_SPATIAL:
break;
case TDS_TYPE_SPATIAL:
break;
}
/* Build a string for bind parameters. */
if (colMetaData[currentColumn].columnTdsType != TDS_TYPE_NVARCHAR || row->isNull[currentColumn] == 'n')
Expand Down Expand Up @@ -2700,10 +2700,13 @@ TdsSendTypeBinary(FmgrInfo *finfo, Datum value, void *vMetaData)
maxLen = 0;
bytea *vlena = DatumGetByteaPCopy(value);
bytea *buf;
int copyLen = 0;
TdsColumnMetaData *col = (TdsColumnMetaData *) vMetaData;

maxLen = col->metaEntry.type7.maxSize;
buf = (bytea *) palloc0(sizeof(bytea) * maxLen);
copyLen = Max((sizeof(bytea) * maxLen), VARSIZE_ANY_EXHDR(vlena));

buf = (bytea *) palloc0(copyLen);
memcpy(buf, VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena));

if ((rc = TdsPutUInt16LE(maxLen)) == 0)
Expand Down Expand Up @@ -3139,6 +3142,7 @@ TdsSendTypeNumeric(FmgrInfo *finfo, Datum value, void *vMetaData)
TdsColumnMetaData *col = (TdsColumnMetaData *) vMetaData;
uint8_t max_scale = col->metaEntry.type5.scale;
uint8_t max_precision = col->metaEntry.type5.precision;
int target_precision = 0;

out = OutputFunctionCall(finfo, value);
if (out[0] == '-')
Expand Down Expand Up @@ -3175,24 +3179,34 @@ TdsSendTypeNumeric(FmgrInfo *finfo, Datum value, void *vMetaData)
if (scale == -1)
scale = 0;

/* Perform the overflow check before scribbling on to decString. */
target_precision = precision + (max_scale - scale);
if (target_precision > TDS_MAX_NUM_PRECISION ||
target_precision > max_precision)
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("Arithmetic overflow error for data type numeric.")));

/*
* Fill in the remaining 0's if the processed scale from out is less than
* max_scale This is needed because the output generated by engine may not
* always produce the same precision/scale as calculated by
* resolve_numeric_typmod_from_exp, which is the precision/scale we have
* sent to the client with column metadata.
*/
* Fill in the remaining 0's if the processed scale from out is less than
* max_scale This is needed because the output generated by engine may not
* always produce the same precision/scale as calculated by
* resolve_numeric_typmod_from_exp, which is the precision/scale we have
* sent to the client with column metadata.
*/
while (scale++ < max_scale)
{
decString[precision++] = '0';
}
decString[precision] = '\0';
Assert(precision <= outlen);
Assert(precision == target_precision);

if (precision > TDS_MAX_NUM_PRECISION ||
precision > max_precision)
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("Arithmetic overflow error for data type numeric.")));
/*
* Verify that we did not go beyond the memory allocated.
* We allow precision < outlen. Consider the case when
* out="123.456", max_scale=8. Then by the end, precision=11
* but outlen=15.
*/
Assert(precision <= outlen);

if (precision >= 1 && precision < 10)
length = 4;
Expand Down Expand Up @@ -4150,16 +4164,16 @@ TdsSendTypeDatetimeoffset(FmgrInfo *finfo, Datum value, void *vMetaData)
return rc;
}

int
int
TdsSendSpatialHelper(FmgrInfo *finfo, Datum value, void *vMetaData, int TdsInstr)
{
int rc = EOF,
npoints,
len, /* number of bytes used to store the string. */
len, /* number of bytes used to store the string. */
actualLen; /* Number of bytes that would be needed to
* store given string in given encoding. */
char *destBuf,
*buf,
char *destBuf,
*buf,
*itr;

int32_t srid;
Expand All @@ -4175,7 +4189,7 @@ TdsSendSpatialHelper(FmgrInfo *finfo, Datum value, void *vMetaData, int TdsInstr
* 16 -> 2 8-Byte float coordinates (TODO: Need to change when Z and M flags are defined for N-dimension Points)
* 6 -> 4 Byte SRID + 2 Byte (01 0C)
*/
len = npoints*16 + 6;
len = npoints*16 + 6;
buf = (char *) palloc0(len);

/* Driver Expects 4 Byte SRID */
Expand All @@ -4196,8 +4210,8 @@ TdsSendSpatialHelper(FmgrInfo *finfo, Datum value, void *vMetaData, int TdsInstr
* First 8 Bytes of gser->data are fixed in PostGIS:
* 4 Bytes -> Represents the Type
* 4 Bytes -> Represents the npoints
*/
memcpy(itr, (char *) gser->data + 8, len - 6);
*/
memcpy(itr, (char *) gser->data + 8, len - 6);

destBuf = TdsEncodingConversion(buf, len, PG_UTF8, col->encoding, &actualLen);

Expand Down
Loading

0 comments on commit 42d99be

Please sign in to comment.