Skip to content

Commit

Permalink
Reimplemented sys.babelfish_concat_wrapper in C to improve the perfor…
Browse files Browse the repository at this point in the history
…mance (#1911)

The '+' operator it took more time to complete the query for concatenation operation which was due to the function babelfish_concat_wrapper was implemented in SQL. In this change, the babelfish_concat_wrapper function is implemented in C. This improves the '+' operator query execution time by 55%

Task: BABEL-4299
Signed-off-by: Parikshit Sarode <[email protected]>
  • Loading branch information
ParikshitSarode authored Oct 20, 2023
1 parent 5865f45 commit 1f5e81e
Show file tree
Hide file tree
Showing 4 changed files with 515 additions and 13 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
54 changes: 54 additions & 0 deletions contrib/babelfishpg_tsql/runtime/functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ typedef enum
OBJECT_TYPE_EXTENDED_STORED_PROCEDURE
} ObjectPropertyType;


PG_FUNCTION_INFO_V1(trancount);
PG_FUNCTION_INFO_V1(version);
PG_FUNCTION_INFO_V1(error);
Expand Down Expand Up @@ -149,6 +150,7 @@ PG_FUNCTION_INFO_V1(pg_extension_config_remove);
PG_FUNCTION_INFO_V1(objectproperty_internal);
PG_FUNCTION_INFO_V1(sysutcdatetime);
PG_FUNCTION_INFO_V1(getutcdate);
PG_FUNCTION_INFO_V1(babelfish_concat_wrapper);

void *string_to_tsql_varchar(const char *input_str);
void *get_servername_internal(void);
Expand Down Expand Up @@ -184,6 +186,58 @@ char *bbf_language = "us_english";
#define MD5_HASH_LEN 32


Datum
babelfish_concat_wrapper(PG_FUNCTION_ARGS)
{
text *arg1, *arg2, *new_text;
int32 arg1_size, arg2_size, new_text_size;
bool first_param = PG_ARGISNULL(0);
bool second_param = PG_ARGISNULL(1);

if (pltsql_concat_null_yields_null)
{
if(first_param || second_param)
{
PG_RETURN_NULL(); // If any is NULL, return NULL
}
}
else
{
if (first_param && second_param)
{
PG_RETURN_NULL(); // If both are NULL, return NULL
}
else if (second_param)
{
PG_RETURN_TEXT_P(PG_GETARG_TEXT_PP(0)); // If only the second string is NULL, return the first string
}
else if (first_param)
{
PG_RETURN_TEXT_P(PG_GETARG_TEXT_PP(1)); // If only the first string is NULL, return the second string
}
}
arg1 = PG_GETARG_TEXT_PP(0);
arg2 = PG_GETARG_TEXT_PP(1);
arg1_size = VARSIZE_ANY_EXHDR(arg1);
arg2_size = VARSIZE_ANY_EXHDR(arg2);

new_text_size = arg1_size + arg2_size + VARHDRSZ;
new_text = (text *) palloc(new_text_size);

SET_VARSIZE(new_text, new_text_size);

if(arg1_size>0)
{
memcpy(VARDATA(new_text), VARDATA_ANY(arg1), arg1_size);
}
if(arg2_size>0)
{
memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size);
}

PG_RETURN_TEXT_P(new_text);
}

Datum
trancount(PG_FUNCTION_ARGS)
{
Expand Down
Loading

0 comments on commit 1f5e81e

Please sign in to comment.