Skip to content

Commit

Permalink
Merge branch 'BABEL_4_X_DEV' into BABEL-4933
Browse files Browse the repository at this point in the history
  • Loading branch information
P Aswini Kumar committed Sep 19, 2024
2 parents 974b690 + 576373c commit 46c9f2e
Show file tree
Hide file tree
Showing 63 changed files with 2,376 additions and 108 deletions.
4 changes: 3 additions & 1 deletion contrib/babelfishpg_common/src/babelfishpg_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@ get_common_utility_plugin(void)
common_utility_plugin_var.is_tsql_rowversion_or_timestamp_datatype = &is_tsql_rowversion_or_timestamp_datatype;
common_utility_plugin_var.datetime_in_str = &datetime_in_str;
common_utility_plugin_var.datetime2sqlvariant = &datetime2sqlvariant;
common_utility_plugin_var.timestamp_datetimeoffset = &timestamp_datetimeoffset;
common_utility_plugin_var.timestamptz_datetimeoffset = &timestamptz_datetimeoffset;
common_utility_plugin_var.timestamptz_datetime2 = &timestamptz_datetime2;
common_utility_plugin_var.timestamptz_datetime = &timestamptz_datetime;
common_utility_plugin_var.datetimeoffset_timestamp = &datetimeoffset_timestamp;
common_utility_plugin_var.tinyint2sqlvariant = &tinyint2sqlvariant;
common_utility_plugin_var.translate_pg_type_to_tsql = &translate_pg_type_to_tsql;
Expand Down
4 changes: 3 additions & 1 deletion contrib/babelfishpg_common/src/babelfishpg_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ typedef struct common_utility_plugin
bool (*is_tsql_rowversion_or_timestamp_datatype) (Oid oid);
Datum (*datetime_in_str) (char *str, Node *escontext);
Datum (*datetime2sqlvariant) (PG_FUNCTION_ARGS);
Datum (*timestamp_datetimeoffset) (PG_FUNCTION_ARGS);
Datum (*timestamptz_datetimeoffset) (PG_FUNCTION_ARGS);
Datum (*timestamptz_datetime2) (PG_FUNCTION_ARGS);
Datum (*timestamptz_datetime) (PG_FUNCTION_ARGS);
Datum (*datetimeoffset_timestamp) (PG_FUNCTION_ARGS);
Datum (*tinyint2sqlvariant) (PG_FUNCTION_ARGS);
Datum (*translate_pg_type_to_tsql) (PG_FUNCTION_ARGS);
Expand Down
38 changes: 38 additions & 0 deletions contrib/babelfishpg_common/src/datetimeoffset.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ PG_FUNCTION_INFO_V1(datetimeoffset_mi);
PG_FUNCTION_INFO_V1(datetimeoffset_hash);
PG_FUNCTION_INFO_V1(datetimeoffset_hash_extended);

PG_FUNCTION_INFO_V1(timestamptz_datetimeoffset);
PG_FUNCTION_INFO_V1(timestamp_datetimeoffset);
PG_FUNCTION_INFO_V1(datetimeoffset_timestamp);
PG_FUNCTION_INFO_V1(date_datetimeoffset);
Expand Down Expand Up @@ -643,6 +644,43 @@ timestamp_datetimeoffset(PG_FUNCTION_ARGS)
PG_RETURN_DATETIMEOFFSET(result);
}

/* timestamptz_datetimeoffset()
* Convert timestamp with time zone to datetimeoffset
*/
Datum
timestamptz_datetimeoffset(PG_FUNCTION_ARGS)
{
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
Timestamp time;
tsql_datetimeoffset *result;

struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
int tz = 0;

if (TIMESTAMP_NOT_FINITE(timestamp))
time = timestamp;
else
{
if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("data out of range for datetimeoffset")));
if (tm2timestamp(tm, fsec, NULL, &time) != 0)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("data out of range for datetimeoffset")));
}

result = (tsql_datetimeoffset *) palloc(DATETIMEOFFSET_LEN);
result->tsql_ts = time;
result->tsql_tz = (int16) tz / 60;
CheckDatetimeoffsetRange(result, fcinfo->context);

PG_RETURN_DATETIMEOFFSET(result);
}

/* datetimeoffset_timestamp()
* Convert datetimeoffset to timestamp
*/
Expand Down
5 changes: 4 additions & 1 deletion contrib/babelfishpg_common/src/datetimeoffset.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#ifndef DATETIMEOFFSET_H
#define DATETIMEOFFSET_H
#include "fmgr.h" // check if necessary
#include "utils/timestamp.h"

/* datetimeoffset size in bytes */
#define DATETIMEOFFSET_LEN MAXALIGN(sizeof(tsql_datetimeoffset))
Expand All @@ -25,7 +26,9 @@ extern void AdjustTimestampForSmallDatetime(Timestamp *time);
extern void CheckSmalldatetimeRange(const Timestamp time, Node *escontext);
extern void CheckDatetimeRange(const Timestamp time, Node *escontext);
extern void CheckDatetime2Range(const Timestamp time, Node *escontext);
extern Datum timestamp_datetimeoffset(PG_FUNCTION_ARGS);
extern Datum timestamptz_datetimeoffset(PG_FUNCTION_ARGS);
extern Datum timestamptz_datetime2(PG_FUNCTION_ARGS);
extern Datum timestamptz_datetime(PG_FUNCTION_ARGS);
extern Datum datetimeoffset_timestamp(PG_FUNCTION_ARGS);
typedef struct tsql_datetimeoffset
{
Expand Down
12 changes: 6 additions & 6 deletions contrib/babelfishpg_tsql/runtime/functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -943,21 +943,21 @@ Datum getutcdate(PG_FUNCTION_ARGS)

Datum getdate_internal(PG_FUNCTION_ARGS)
{
PG_RETURN_DATUM(DirectFunctionCall2(timestamp_trunc,CStringGetTextDatum("millisecond"),
TimestampTzGetDatum(GetCurrentStatementStartTimestamp())));
PG_RETURN_DATUM(DirectFunctionCall1(common_utility_plugin_ptr->timestamptz_datetime,
DirectFunctionCall2(timestamptz_trunc,CStringGetTextDatum("millisecond"),
TimestampTzGetDatum(GetCurrentStatementStartTimestamp()))));

}

Datum sysdatetime(PG_FUNCTION_ARGS)
{
PG_RETURN_TIMESTAMPTZ(GetCurrentStatementStartTimestamp());
PG_RETURN_DATUM(DirectFunctionCall1(common_utility_plugin_ptr->timestamptz_datetime2,
TimestampTzGetDatum(GetCurrentStatementStartTimestamp())));
}

Datum sysdatetimeoffset(PG_FUNCTION_ARGS)
{


PG_RETURN_DATUM(DirectFunctionCall1(common_utility_plugin_ptr->timestamp_datetimeoffset,
PG_RETURN_DATUM(DirectFunctionCall1(common_utility_plugin_ptr->timestamptz_datetimeoffset,
TimestampTzGetDatum(GetCurrentStatementStartTimestamp())));
}

Expand Down
98 changes: 34 additions & 64 deletions contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -912,63 +912,6 @@ AND has_schema_privilege(t1.relnamespace, 'USAGE')
AND has_table_privilege(t1.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER');
GRANT SELECT ON sys.sp_tables_view TO PUBLIC;
CREATE OR REPLACE FUNCTION sys.sp_tables_internal(
in_table_name sys.nvarchar(384) = NULL,
in_table_owner sys.nvarchar(384) = NULL,
in_table_qualifier sys.sysname = NULL,
in_table_type sys.varchar(100) = NULL,
in_fusepattern sys.bit = '1')
RETURNS TABLE (
out_table_qualifier sys.sysname,
out_table_owner sys.sysname,
out_table_name sys.sysname,
out_table_type sys.varchar(32),
out_remarks sys.varchar(254)
)
AS $$
DECLARE opt_table sys.varchar(16) = '';
DECLARE opt_view sys.varchar(16) = '';
DECLARE cs_as_in_table_type varchar COLLATE "C" = in_table_type;
BEGIN
IF upper(cs_as_in_table_type) LIKE '%''TABLE''%' THEN
opt_table = 'TABLE';
END IF;
IF upper(cs_as_in_table_type) LIKE '%''VIEW''%' THEN
opt_view = 'VIEW';
END IF;
IF in_fusepattern = 1 THEN
RETURN query
SELECT
CAST(table_qualifier AS sys.sysname) AS TABLE_QUALIFIER,
CAST(table_owner AS sys.sysname) AS TABLE_OWNER,
CAST(table_name AS sys.sysname) AS TABLE_NAME,
CAST(table_type AS sys.varchar(32)) AS TABLE_TYPE,
CAST(remarks AS sys.varchar(254)) AS REMARKS
FROM sys.sp_tables_view
WHERE (in_table_name IS NULL OR table_name LIKE in_table_name collate sys.database_default)
AND (in_table_owner IS NULL OR table_owner LIKE in_table_owner collate sys.database_default)
AND (in_table_qualifier IS NULL OR table_qualifier LIKE in_table_qualifier collate sys.database_default)
AND (cs_as_in_table_type IS NULL OR table_type = opt_table OR table_type = opt_view)
ORDER BY table_qualifier, table_owner, table_name;
ELSE
RETURN query
SELECT
CAST(table_qualifier AS sys.sysname) AS TABLE_QUALIFIER,
CAST(table_owner AS sys.sysname) AS TABLE_OWNER,
CAST(table_name AS sys.sysname) AS TABLE_NAME,
CAST(table_type AS sys.varchar(32)) AS TABLE_TYPE,
CAST(remarks AS sys.varchar(254)) AS REMARKS
FROM sys.sp_tables_view
WHERE (in_table_name IS NULL OR table_name = in_table_name collate sys.database_default)
AND (in_table_owner IS NULL OR table_owner = in_table_owner collate sys.database_default)
AND (in_table_qualifier IS NULL OR table_qualifier = in_table_qualifier collate sys.database_default)
AND (cs_as_in_table_type IS NULL OR table_type = opt_table OR table_type = opt_view)
ORDER BY table_qualifier, table_owner, table_name;
END IF;
END;
$$
LANGUAGE plpgsql STABLE;
CREATE OR REPLACE PROCEDURE sys.sp_tables (
"@table_name" sys.nvarchar(384) = NULL,
"@table_owner" sys.nvarchar(384) = NULL,
Expand Down Expand Up @@ -997,13 +940,40 @@ BEGIN
THROW 33557097, N'The database name component of the object qualifier must be the name of the current database.', 1;
END
SELECT
CAST(out_table_qualifier AS sys.sysname) AS TABLE_QUALIFIER,
CAST(out_table_owner AS sys.sysname) AS TABLE_OWNER,
CAST(out_table_name AS sys.sysname) AS TABLE_NAME,
CAST(out_table_type AS sys.varchar(32)) AS TABLE_TYPE,
CAST(out_remarks AS sys.varchar(254)) AS REMARKS
FROM sys.sp_tables_internal(@table_name, @table_owner, @table_qualifier, CAST(@table_type AS varchar(100)), @fusepattern);
IF (@fusepattern = 1)
SELECT
CAST(table_qualifier AS sys.sysname) AS TABLE_QUALIFIER,
CAST(table_owner AS sys.sysname) AS TABLE_OWNER,
CAST(table_name AS sys.sysname) AS TABLE_NAME,
CAST(table_type AS sys.varchar(32)) AS TABLE_TYPE,
remarks AS REMARKS
FROM sys.sp_tables_view
WHERE (@table_name IS NULL OR table_name LIKE @table_name collate database_default)
AND (@table_owner IS NULL OR table_owner LIKE @table_owner collate database_default)
AND (@table_qualifier IS NULL OR table_qualifier LIKE @table_qualifier collate database_default)
AND (
@table_type IS NULL OR
(CAST(@table_type AS varchar(100)) LIKE '%''TABLE''%' collate database_default AND table_type = 'TABLE' collate database_default) OR
(CAST(@table_type AS varchar(100)) LIKE '%''VIEW''%' collate database_default AND table_type = 'VIEW' collate database_default)
)
ORDER BY TABLE_QUALIFIER, TABLE_OWNER, TABLE_NAME;
ELSE
SELECT
CAST(table_qualifier AS sys.sysname) AS TABLE_QUALIFIER,
CAST(table_owner AS sys.sysname) AS TABLE_OWNER,
CAST(table_name AS sys.sysname) AS TABLE_NAME,
CAST(table_type AS sys.varchar(32)) AS TABLE_TYPE,
remarks AS REMARKS
FROM sys.sp_tables_view
WHERE (@table_name IS NULL OR table_name = @table_name collate database_default)
AND (@table_owner IS NULL OR table_owner = @table_owner collate database_default)
AND (@table_qualifier IS NULL OR table_qualifier = @table_qualifier collate database_default)
AND (
@table_type IS NULL OR
(CAST(@table_type AS varchar(100)) LIKE '%''TABLE''%' collate database_default AND table_type = 'TABLE' collate database_default) OR
(CAST(@table_type AS varchar(100)) LIKE '%''VIEW''%' collate database_default AND table_type = 'VIEW' collate database_default)
)
ORDER BY TABLE_QUALIFIER, TABLE_OWNER, TABLE_NAME;
END;
$$
LANGUAGE 'pltsql';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,33 @@
-- add 'sys' to search path for the convenience
SELECT set_config('search_path', 'sys, '||current_setting('search_path'), false);

-- Drops an object if it does not have any dependent objects.
-- Is a temporary procedure for use by the upgrade script. Will be dropped at the end of the upgrade.
-- Please have this be one of the first statements executed in this upgrade script.
CREATE OR REPLACE PROCEDURE babelfish_drop_deprecated_object(object_type varchar, schema_name varchar, object_name varchar) AS
$$
DECLARE
error_msg text;
query1 text;
query2 text;
BEGIN

query1 := pg_catalog.format('alter extension babelfishpg_tsql drop %s %s.%s', object_type, schema_name, object_name);
query2 := pg_catalog.format('drop %s %s.%s', object_type, schema_name, object_name);

execute query1;
execute query2;
EXCEPTION
when object_not_in_prerequisite_state then --if 'alter extension' statement fails
GET STACKED DIAGNOSTICS error_msg = MESSAGE_TEXT;
raise warning '%', error_msg;
when dependent_objects_still_exist then --if 'drop view' statement fails
GET STACKED DIAGNOSTICS error_msg = MESSAGE_TEXT;
raise warning '%', error_msg;
end
$$
LANGUAGE plpgsql;

-- Please add your SQLs here
/*
* Note: These SQL statements may get executed multiple times specially when some features get backpatched.
Expand Down Expand Up @@ -1755,6 +1782,81 @@ AND pg_get_serial_sequence(quote_ident(ext.nspname)||'.'||quote_ident(c.relname)
AND has_sequence_privilege(pg_get_serial_sequence(quote_ident(ext.nspname)||'.'||quote_ident(c.relname), a.attname), 'USAGE,SELECT,UPDATE');
GRANT SELECT ON sys.identity_columns TO PUBLIC;
CREATE OR REPLACE PROCEDURE sys.sp_tables (
"@table_name" sys.nvarchar(384) = NULL,
"@table_owner" sys.nvarchar(384) = NULL,
"@table_qualifier" sys.sysname = NULL,
"@table_type" sys.nvarchar(100) = NULL,
"@fusepattern" sys.bit = '1')
AS $$
BEGIN
-- Handle special case: Enumerate all databases when name and owner are blank but qualifier is '%'
IF (@table_qualifier = '%' AND @table_owner = '' AND @table_name = '')
BEGIN
SELECT
d.name AS TABLE_QUALIFIER,
CAST(NULL AS sys.sysname) AS TABLE_OWNER,
CAST(NULL AS sys.sysname) AS TABLE_NAME,
CAST(NULL AS sys.varchar(32)) AS TABLE_TYPE,
CAST(NULL AS sys.varchar(254)) AS REMARKS
FROM sys.databases d ORDER BY TABLE_QUALIFIER;
RETURN;
END;
IF (@table_qualifier != '' AND LOWER(@table_qualifier) != LOWER(sys.db_name()))
BEGIN
THROW 33557097, N'The database name component of the object qualifier must be the name of the current database.', 1;
END
IF (@fusepattern = 1)
SELECT
CAST(table_qualifier AS sys.sysname) AS TABLE_QUALIFIER,
CAST(table_owner AS sys.sysname) AS TABLE_OWNER,
CAST(table_name AS sys.sysname) AS TABLE_NAME,
CAST(table_type AS sys.varchar(32)) AS TABLE_TYPE,
remarks AS REMARKS
FROM sys.sp_tables_view
WHERE (@table_name IS NULL OR table_name LIKE @table_name collate database_default)
AND (@table_owner IS NULL OR table_owner LIKE @table_owner collate database_default)
AND (@table_qualifier IS NULL OR table_qualifier LIKE @table_qualifier collate database_default)
AND (
@table_type IS NULL OR
(CAST(@table_type AS varchar(100)) LIKE '%''TABLE''%' collate database_default AND table_type = 'TABLE' collate database_default) OR
(CAST(@table_type AS varchar(100)) LIKE '%''VIEW''%' collate database_default AND table_type = 'VIEW' collate database_default)
)
ORDER BY TABLE_QUALIFIER, TABLE_OWNER, TABLE_NAME;
ELSE
SELECT
CAST(table_qualifier AS sys.sysname) AS TABLE_QUALIFIER,
CAST(table_owner AS sys.sysname) AS TABLE_OWNER,
CAST(table_name AS sys.sysname) AS TABLE_NAME,
CAST(table_type AS sys.varchar(32)) AS TABLE_TYPE,
remarks AS REMARKS
FROM sys.sp_tables_view
WHERE (@table_name IS NULL OR table_name = @table_name collate database_default)
AND (@table_owner IS NULL OR table_owner = @table_owner collate database_default)
AND (@table_qualifier IS NULL OR table_qualifier = @table_qualifier collate database_default)
AND (
@table_type IS NULL OR
(CAST(@table_type AS varchar(100)) LIKE '%''TABLE''%' collate database_default AND table_type = 'TABLE' collate database_default) OR
(CAST(@table_type AS varchar(100)) LIKE '%''VIEW''%' collate database_default AND table_type = 'VIEW' collate database_default)
)
ORDER BY TABLE_QUALIFIER, TABLE_OWNER, TABLE_NAME;
END;
$$
LANGUAGE 'pltsql';
GRANT EXECUTE ON PROCEDURE sys.sp_tables TO PUBLIC;
ALTER FUNCTION sys.sp_tables_internal RENAME TO sp_tables_internal_deprecated_in_4_4_0;
CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'sp_tables_internal_deprecated_in_4_4_0');
-- 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);
-- After upgrade, always run analyze for all babelfish catalogs.
CALL sys.analyze_babelfish_catalogs();
Expand Down
36 changes: 36 additions & 0 deletions test/JDBC/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The JDBC test framework for Babelfish uses the JDBC Driver for SQL Server for da
- [Adding the test cases](#adding-the-test-cases)
- [Reading the console output and diff](#reading-the-console-output-and-diff)
- [Running Tests with Parallel Query Enabled](#running-tests-with-parallel-query-enabled)
- [Running Tests with Single-DB Migration Mode](#running-tests-with-single-db-migration-mode)
- [Running Tests with Non Default Server Collation](#running-tests-with-non-default-server-collation)
- [Running Tests with Non Default Database Collation](#running-tests-with-non-default-database-collation)

Expand Down Expand Up @@ -463,6 +464,41 @@ After building the modified PostgreSQL engine and Babelfish extensions using the
```
If you encounter failing or crashing tests in the "JDBC tests with parallel query" GitHub workflow, consider adding the names of these problematic test cases to the `parallel_query_jdbc_schedule` file. Prefix these test case names with `ignore#!#`. As we work towards resolving these issues in the future, we will gradually remove these excluded tests from the `parallel_query_jdbc_schedule` scheduling file.
## Running Tests with Single-DB Migration Mode
After building the modified PostgreSQL engine and Babelfish extensions using the [online instructions](../../contrib/README.md), you must:
1. Create a PostgreSQL database and initialize Babelfish extensions with single-db migration mode by adding following line in `postgres/data/postgresql.conf` and restart engine, then initialize Babelfish extensions using the [online instructions](../../contrib/README.md)
```bash
babelfishpg_tsql.migration_mode = 'single-db'
```
2. Before running JDBC tests, set the `isSingleDbMode` environment variable to `true`:
```bash
export isSingleDbMode=true
# Verify if isSingleDbMode is set to true
echo $isSingleDbMode
```
3. Now Run the tests:
```bash
mvn test
```
4. How to add expected output for some test
1. By default expected output of a test should be added into `expected` folder.
2. If the expected output is different for single-db migration mode compared to multi-db migration mode, one can add a different expected output specially for single-db migration mode in `expected/single_db/` folder. Additionally, one needs to add `-- single_db_mode_expected` flag in the corresponding input file.
5. To exclude some tests from running via the JDBC in single-db migration mode, you can add test-case name with prefix `ignore#!#` in `singledb_jdbc_schedule` file.
6. Cleanup all the objects, users, roles and databases created while running the tests:
```bash
./cleanup.sh
```
7. Please note that whenever you had changed the migration mode and reinitialised Babelfish extensions. Update the `isSingleDbMode` environment variable with appropriate value and unset when migration mode is set to 'multi-db'.
```bash
unset isSingleDbMode
```
This ensures that correct expected output is picked for current migration mode.
## Running Tests with Non Default Server Collation
After building the modified PostgreSQL engine and Babelfish extensions using the [online instructions](../../contrib/README.md), you must:
Expand Down
Loading

0 comments on commit 46c9f2e

Please sign in to comment.