Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/BABEL_4_X_DEV' into babel-5454
Browse files Browse the repository at this point in the history
  • Loading branch information
Tanya Gupta committed Feb 4, 2025
2 parents d310c59 + 0453ce3 commit 584c1f9
Show file tree
Hide file tree
Showing 80 changed files with 2,236 additions and 201 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ runs:
else
ENGINE_BRANCH=${{inputs.engine_branch}}
fi
REPOSITORY_OWNER=$HEAD_OWNER
REPOSITORY_OWNER=${{ github.event.pull_request.head.repo.owner.login }}
else
if [[ ${{inputs.engine_branch}} == "latest" ]]; then
ENGINE_BRANCH=$GITHUB_REF_NAME
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ RETURNS sys.BPCHAR
AS 'babelfishpg_common', 'fixeddecimal2bpchar'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.float82varchar(pg_catalog.float8, integer, BOOLEAN)
RETURNS sys.VARCHAR
AS 'babelfishpg_common', 'float82varchar'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.float82bpchar(pg_catalog.float8, integer, BOOLEAN)
RETURNS sys.BPCHAR
AS 'babelfishpg_common', 'float82bpchar'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

DO $$
DECLARE
exception_message text;
Expand Down Expand Up @@ -136,6 +146,22 @@ CREATE OPERATOR sys.% (
END IF;
END $$;

DO $$
DECLARE
exception_message text;
BEGIN
CREATE CAST (pg_catalog.float8 AS sys.VARCHAR)
WITH FUNCTION sys.float82varchar(pg_catalog.float8, integer, BOOLEAN) AS IMPLICIT;

CREATE CAST (pg_catalog.float8 AS sys.BPCHAR)
WITH FUNCTION sys.float82bpchar(pg_catalog.float8, integer, BOOLEAN) AS IMPLICIT;
EXCEPTION WHEN duplicate_object THEN
GET STACKED DIAGNOSTICS
exception_message = MESSAGE_TEXT;
RAISE WARNING '%', exception_message;
END;
$$;

CREATE OR REPLACE FUNCTION sys.moneylarger(sys.MONEY, sys.MONEY)
RETURNS sys.MONEY
AS 'babelfishpg_money', 'fixeddecimallarger'
Expand Down
16 changes: 16 additions & 0 deletions contrib/babelfishpg_common/sql/varchar.sql
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,19 @@ CREATE OR REPLACE AGGREGATE sys.min(sys.NVARCHAR)
combinefunc = sys.nvarchar_smaller,
parallel = safe
);

CREATE OR REPLACE FUNCTION sys.float82varchar(pg_catalog.float8, integer, BOOLEAN)
RETURNS sys.VARCHAR
AS 'babelfishpg_common', 'float82varchar'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.float82bpchar(pg_catalog.float8, integer, BOOLEAN)
RETURNS sys.BPCHAR
AS 'babelfishpg_common', 'float82bpchar'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

CREATE CAST (pg_catalog.float8 AS sys.VARCHAR)
WITH FUNCTION sys.float82varchar(pg_catalog.float8, integer, BOOLEAN) AS IMPLICIT;

CREATE CAST (pg_catalog.float8 AS sys.BPCHAR)
WITH FUNCTION sys.float82bpchar(pg_catalog.float8, integer, BOOLEAN) AS IMPLICIT;
102 changes: 102 additions & 0 deletions contrib/babelfishpg_common/src/varchar.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "access/hash.h"
#include "collation.h"
#include "common/shortest_dec.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "encoding/encoding.h"
Expand Down Expand Up @@ -562,6 +563,8 @@ PG_FUNCTION_INFO_V1(varchar2money);
PG_FUNCTION_INFO_V1(varchar2numeric);
PG_FUNCTION_INFO_V1(fixeddecimal2varchar);
PG_FUNCTION_INFO_V1(fixeddecimal2bpchar);
PG_FUNCTION_INFO_V1(float82varchar);
PG_FUNCTION_INFO_V1(float82bpchar);

/*****************************************************************************
* varchar - varchar(n)
Expand Down Expand Up @@ -1188,6 +1191,105 @@ fixeddecimal2bpchar(PG_FUNCTION_ARGS)
#undef FIXEDDECIMAL_2_VARCHAR_MULTIPLIER
#undef FIXEDDECIMAL_2_VARCHAR_SCALE

Datum
float82varchar(PG_FUNCTION_ARGS)
{
float8 num = PG_GETARG_FLOAT8(0);
int32 typmod = PG_GETARG_INT32(1);
/* When No Typmod is defined Default Length is 30 */
int maxlen = (typmod == -1) ? 30 : (typmod - VARHDRSZ);
Datum res;
/* 32 length as double_to_shortest_decimal_buf always returns string with length less that 30*/
char *ascii = (char *) palloc0(32);

/* round to 6 decimal digits */
if (unlikely(isinf(num)|| isnan(num)))
{
ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION),
errmsg("Error Converting Float Value to String.")));
}
else
{
num = round(num * 1000000.0) / 1000000.0;
}

double_to_shortest_decimal_buf(num, ascii);

/* Check if the number fits within the specified length */
if (maxlen > 0)
{
size_t str_len = strlen(ascii);
if (str_len > maxlen)
{
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
errmsg("There is insufficient result space to convert a float value to varchar/nvarchar.")));
}
}

res = DirectFunctionCall3(varcharin,
CStringGetDatum(ascii),
ObjectIdGetDatum(0),
Int32GetDatum(typmod));

PG_RETURN_DATUM(res);

}

Datum
float82bpchar(PG_FUNCTION_ARGS)
{
float8 num = PG_GETARG_FLOAT8(0);
int32 typmod = PG_GETARG_INT32(1);
/* When No Typmod is defined Default Length is 30 */
int maxlen = (typmod == -1) ? 30 : (typmod - VARHDRSZ);
Datum res;
/* 32 length as double_to_shortest_decimal_buf always returns string with length less that 30*/
char *ascii = (char *) palloc0(32);
char *buf_padded;
int str_len = -1;

/* Handle special cases */
if (unlikely(isinf(num)|| isnan(num)))
{
ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION),
errmsg("Error Converting Float Value to String.")));
}
else
{
num = round(num * 1000000.0) / 1000000.0;
}

double_to_shortest_decimal_buf(num, ascii);

/* Check if the number fits within the specified length */
if (maxlen > 0)
{
str_len = strlen(ascii);
if (str_len > maxlen)
{
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
errmsg("There is insufficient result space to convert a float value to char/nchar.")));
}
}

/* Left pad float value with the spaces */
buf_padded = (char *) palloc0(maxlen + 1);
memset(buf_padded, ' ', maxlen - str_len);
memcpy(buf_padded + maxlen - str_len, ascii, str_len);

res = DirectFunctionCall3(bpcharin,
CStringGetDatum(buf_padded),
ObjectIdGetDatum(0),
Int32GetDatum(typmod));

PG_RETURN_DATUM(res);

}

/*****************************************************************************
* bpchar - char() *
*****************************************************************************/
Expand Down
12 changes: 7 additions & 5 deletions contrib/babelfishpg_tsql/sql/sys_function_helpers.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10020,13 +10020,15 @@ BEGIN
END IF;
IF (v_floatval >= 999999.5) THEN
v_format := '9D99999EEEE';
v_result := to_char(v_sign * ceiling(v_floatval), v_format);
v_result := to_char(v_sign::NUMERIC * ceiling(v_floatval), v_format);
v_result := to_char(substring(v_result, 1, 8)::NUMERIC, 'FM9D99999')::NUMERIC::TEXT || substring(v_result, 9);
ELSE
if (6 - v_integral_digits < v_decimal_digits) THEN
v_decimal_digits := 6 - v_integral_digits;
END IF;
v_format := (pow(10, v_integral_digits)-1)::TEXT || 'D';
IF (6 - v_integral_digits < v_decimal_digits) AND (trunc(abs(v_floatval)) != 0) THEN
v_decimal_digits := 6 - v_integral_digits;
ELSIF (6 - v_integral_digits < v_decimal_digits) THEN
v_decimal_digits := 6;
END IF;
v_format := (pow(10, v_integral_digits)-10)::TEXT || 'D';
IF (v_decimal_digits > 0) THEN
v_format := v_format || (pow(10, v_decimal_digits)-1)::TEXT;
END IF;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11744,6 +11744,79 @@ RETURNS NULL ON NULL INPUT;

CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'babelfish_try_conv_money_to_string_deprecated_in_4_5_0');

CREATE OR REPLACE FUNCTION sys.babelfish_try_conv_float_to_string(IN p_datatype TEXT,
IN p_floatval FLOAT,
IN p_style NUMERIC DEFAULT 0)
RETURNS TEXT
AS
$BODY$
DECLARE
v_style SMALLINT;
v_format VARCHAR COLLATE "C";
v_floatval NUMERIC := abs(p_floatval);
v_digits SMALLINT;
v_integral_digits SMALLINT;
v_decimal_digits SMALLINT;
v_sign SMALLINT := sign(p_floatval);
v_result TEXT;
v_res_length SMALLINT;
MASK_REGEXP CONSTANT VARCHAR COLLATE "C" := '^\s*(?:character varying)\s*\(\s*(\d+|MAX)\s*\)\s*$';
BEGIN
v_style := floor(p_style)::SMALLINT;
IF (v_style = 0) THEN
v_digits := length(v_floatval::NUMERIC::TEXT);
v_decimal_digits := scale(v_floatval);
IF (v_decimal_digits > 0) THEN
v_integral_digits := v_digits - v_decimal_digits - 1;
ELSE
v_integral_digits := v_digits;
END IF;
IF (v_floatval >= 999999.5) THEN
v_format := '9D99999EEEE';
v_result := to_char(v_sign::NUMERIC * ceiling(v_floatval), v_format);
v_result := to_char(substring(v_result, 1, 8)::NUMERIC, 'FM9D99999')::NUMERIC::TEXT || substring(v_result, 9);
ELSE
IF (6 - v_integral_digits < v_decimal_digits) AND (trunc(abs(v_floatval)) != 0) THEN
v_decimal_digits := 6 - v_integral_digits;
ELSIF (6 - v_integral_digits < v_decimal_digits) THEN
v_decimal_digits := 6;
END IF;
v_format := (pow(10, v_integral_digits)-10)::TEXT || 'D';
IF (v_decimal_digits > 0) THEN
v_format := v_format || (pow(10, v_decimal_digits)-1)::TEXT;
END IF;
v_result := to_char(p_floatval, v_format);
END IF;
ELSIF (v_style = 1) THEN
v_format := '9D9999999EEEE';
v_result := to_char(p_floatval, v_format);
ELSIF (v_style = 2) THEN
v_format := '9D999999999999999EEEE';
v_result := to_char(p_floatval, v_format);
ELSIF (v_style = 3) THEN
v_format := '9D9999999999999999EEEE';
v_result := to_char(p_floatval, v_format);
ELSE
RAISE invalid_parameter_value;
END IF;

v_res_length := substring(p_datatype COLLATE "C", MASK_REGEXP)::SMALLINT;
IF v_res_length IS NULL THEN
RETURN v_result;
ELSE
RETURN rpad(v_result, v_res_length, ' ');
END IF;
EXCEPTION
WHEN invalid_parameter_value THEN
RAISE USING MESSAGE := pg_catalog.format('%s is not a valid style number when converting from FLOAT to a character string.', v_style),
DETAIL := 'Use of incorrect "style" parameter value during conversion process.',
HINT := 'Change "style" parameter to the proper value and try again.';
END;
$BODY$
LANGUAGE plpgsql
STABLE
RETURNS NULL ON NULL INPUT;

-- Drops the temporary procedure used by the upgrade script.
-- Please have this be one of the last statements executed in this upgrade script.
DROP PROCEDURE sys.babelfish_drop_deprecated_object(varchar, varchar, varchar);
Expand Down
4 changes: 0 additions & 4 deletions contrib/babelfishpg_tsql/src/pltsql_coerce.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,6 @@ tsql_cast_raw_info_t tsql_cast_raw_infos[] =
{TSQL_CAST_WITHOUT_FUNC_ENTRY, "pg_catalog", "float4", "sys", "varchar", NULL, 'i', 'i'},
/* float8 -> string via I/O */
{TSQL_CAST_WITHOUT_FUNC_ENTRY, "pg_catalog", "float8", "pg_catalog", "text", NULL, 'i', 'i'},
{TSQL_CAST_WITHOUT_FUNC_ENTRY, "pg_catalog", "float8", "pg_catalog", "bpchar", NULL, 'i', 'i'},
{TSQL_CAST_WITHOUT_FUNC_ENTRY, "pg_catalog", "float8", "sys", "bpchar", NULL, 'i', 'i'},
{TSQL_CAST_WITHOUT_FUNC_ENTRY, "pg_catalog", "float8", "pg_catalog", "varchar", NULL, 'i', 'i'},
{TSQL_CAST_WITHOUT_FUNC_ENTRY, "pg_catalog", "float8", "sys", "varchar", NULL, 'i', 'i'},
/* numeric -> string via I/O */
{TSQL_CAST_WITHOUT_FUNC_ENTRY, "pg_catalog", "numeric", "pg_catalog", "text", NULL, 'i', 'i'},
{TSQL_CAST_WITHOUT_FUNC_ENTRY, "pg_catalog", "numeric", "pg_catalog", "bpchar", NULL, 'i', 'i'},
Expand Down
6 changes: 3 additions & 3 deletions test/JDBC/expected/BABEL-1193.out
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ SELECT * FROM t15;
GO
~~START~~
char#!#char#!#char#!#char#!#char#!#char#!#char#!#char
12 #!#4553 #!#123456 #!#12.345 #!#2344.456 #!#12.34 #!# 456.33#!# 1123.68
-12 #!#-1234 #!#-123456 #!#-12.345 #!#-2344.456 #!#12.34 #!# -456.33#!# -1123.68
0 #!#0 #!#0 #!#0 #!#0 #!#0.00 #!# 0.00#!# 0.00
12 #!#4553 #!#123456 #!#12.345 #!# 2344.456#!#12.34 #!# 456.33#!# 1123.68
-12 #!#-1234 #!#-123456 #!#-12.345 #!# -2344.456#!#12.34 #!# -456.33#!# -1123.68
0 #!#0 #!#0 #!#0 #!# 0#!#0.00 #!# 0.00#!# 0.00
~~END~~


Expand Down
18 changes: 12 additions & 6 deletions test/JDBC/expected/BABEL-2998.out
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,76 @@
SELECT CAST('1' AS CHAR(10)) AS Col1
UNION
SELECT NULL AS Col1
ORDER BY Col1
GO
~~START~~
char
1
<NULL>
1
~~END~~


SELECT CAST('1' AS CHAR(10)) AS Col1
UNION ALL
SELECT NULL AS Col1
GROUP BY Col1
ORDER BY Col1
GO
~~START~~
char
1
<NULL>
1
~~END~~


-- taking suggestion from above error, added explicit CAST and CONVERT
SELECT CAST('1' AS CHAR(10)) AS Col1
UNION
SELECT CAST(NULL AS CHAR(10)) AS Col1
ORDER BY Col1
GO
~~START~~
char
1
<NULL>
1
~~END~~


SELECT CAST('1' AS CHAR(10)) AS Col1
UNION ALL
SELECT CONVERT(CHAR(10), NULL) AS Col1
GROUP BY Col1
ORDER BY Col1
GO
~~START~~
char
1
<NULL>
1
~~END~~


SELECT CAST('1' AS CHAR(10)) AS Col1
UNION ALL
SELECT CAST(NULL AS CHAR(10)) AS Col1
GROUP BY Col1
ORDER BY Col1
GO
~~START~~
char
1
<NULL>
1
~~END~~


SELECT CAST('1' AS CHAR(10)) AS Col1
UNION
SELECT CONVERT(CHAR(10), NULL) AS Col1
ORDER BY Col1
GO
~~START~~
char
1
<NULL>
1
~~END~~


Expand Down
Loading

0 comments on commit 584c1f9

Please sign in to comment.