Skip to content

Commit

Permalink
Support Rowversion datatype with Insert Bulk (babelfish-for-postgresq…
Browse files Browse the repository at this point in the history
…l#776)

Added support for rowversion/timestamp datatype with Insert Bulk.
Currently no operation happens when we do insert bulk for table having rowversion/timestamp datatype. With this changes added support for rowversion colmetadata and a default value of rowversion is inserted for all rows inserted during an insert bulk operation.

Issues Resolved: BABEL-3584
Signed-off-by: Shlok Kyal skkyal@amazon.com
  • Loading branch information
skkyal authored Nov 10, 2022
1 parent e67ca05 commit 0d522ce
Show file tree
Hide file tree
Showing 28 changed files with 650 additions and 6 deletions.
1 change: 1 addition & 0 deletions contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ BEGIN
WHEN 'datetime2' THEN tds_id = 42;
WHEN 'sql_variant' THEN tds_id = 98;
WHEN 'datetimeoffset' THEN tds_id = 43;
WHEN 'timestamp' THEN tds_id = 173;
ELSE tds_id = 0;
END CASE;
RETURN tds_id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4120,6 +4120,62 @@ ALTER FUNCTION sys.get_max_id_from_table RENAME TO get_max_id_from_table_depreca
CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'get_min_id_from_table_deprecated_in_2_3_0');
CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'get_max_id_from_table_deprecated_in_2_3_0');


-- Deprecate the function sys.get_tds_id
ALTER FUNCTION sys.get_tds_id RENAME TO get_tds_id_deprecated_2_3_0;

-- Recreate Newer sys.get_tds_id function
create or replace function sys.get_tds_id(
datatype sys.varchar(50)
)
returns INT
AS $$
DECLARE
tds_id INT;
BEGIN
IF datatype IS NULL THEN
RETURN 0;
END IF;
CASE datatype
WHEN 'text' THEN tds_id = 35;
WHEN 'uniqueidentifier' THEN tds_id = 36;
WHEN 'tinyint' THEN tds_id = 38;
WHEN 'smallint' THEN tds_id = 38;
WHEN 'int' THEN tds_id = 38;
WHEN 'bigint' THEN tds_id = 38;
WHEN 'ntext' THEN tds_id = 99;
WHEN 'bit' THEN tds_id = 104;
WHEN 'float' THEN tds_id = 109;
WHEN 'real' THEN tds_id = 109;
WHEN 'varchar' THEN tds_id = 167;
WHEN 'nvarchar' THEN tds_id = 231;
WHEN 'nchar' THEN tds_id = 239;
WHEN 'money' THEN tds_id = 110;
WHEN 'smallmoney' THEN tds_id = 110;
WHEN 'char' THEN tds_id = 175;
WHEN 'date' THEN tds_id = 40;
WHEN 'datetime' THEN tds_id = 111;
WHEN 'smalldatetime' THEN tds_id = 111;
WHEN 'numeric' THEN tds_id = 108;
WHEN 'xml' THEN tds_id = 241;
WHEN 'decimal' THEN tds_id = 106;
WHEN 'varbinary' THEN tds_id = 165;
WHEN 'binary' THEN tds_id = 173;
WHEN 'image' THEN tds_id = 34;
WHEN 'time' THEN tds_id = 41;
WHEN 'datetime2' THEN tds_id = 42;
WHEN 'sql_variant' THEN tds_id = 98;
WHEN 'datetimeoffset' THEN tds_id = 43;
WHEN 'timestamp' THEN tds_id = 173;
ELSE tds_id = 0;
END CASE;
RETURN tds_id;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;

-- Drop the deprecated function
CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'get_tds_id_deprecated_2_3_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);
Expand Down
16 changes: 15 additions & 1 deletion contrib/babelfishpg_tsql/src/pltsql_bulkcopy.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "catalog/dependency.h"
#include "catalog/namespace.h"
#include "commands/sequence.h"
#include "commands/copy.h"
#include "executor/executor.h"
#include "executor/nodeModifyTable.h"
#include "executor/tuptable.h"
Expand Down Expand Up @@ -202,6 +203,13 @@ BulkCopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
errmsg("column \"%s\" is a Computed column",
name),
errdetail("Computed columns cannot be used in BULK COPY.")));
else if (is_tsql_rowversion_or_timestamp_datatype_hook && is_tsql_rowversion_or_timestamp_datatype_hook(att->atttypid))
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
errmsg("column \"%s\" is a ROWVERSION/TIMESTAMP column",
name),
errdetail("ROWVERSION/TIMESTAMP columns cannot be used in BULK COPY.")));

attnum = att->attnum;
break;
}
Expand Down Expand Up @@ -722,7 +730,7 @@ ExecuteBulkCopy(BulkCopyState cstate, int rowCount, int colCount,
Assert(econtext != NULL);
Assert(CurrentMemoryContext == econtext->ecxt_per_tuple_memory);

if (myslot->tts_isnull[defmap[i]] && !insert_bulk_keep_nulls)
if (myslot->tts_isnull[defmap[i]] && (!insert_bulk_keep_nulls || cstate->rv_index == defmap[i]))
myslot->tts_values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext,
&myslot->tts_isnull[defmap[i]]);
}
Expand Down Expand Up @@ -874,6 +882,7 @@ BeginBulkCopy(Relation rel,
cstate->cur_relname = RelationGetRelationName(cstate->rel);
cstate->cur_rowno = 0;
cstate->seq_index = -1;
cstate->rv_index = -1;

/* Assign range table. */
cstate->range_table = pstate->p_rtable;
Expand Down Expand Up @@ -908,6 +917,11 @@ BeginBulkCopy(Relation rel,
{
Expr *defexpr = (Expr *) build_column_default(cstate->rel,
attnum);

/* Save the index for the rowversion datatype */
if (is_tsql_rowversion_or_timestamp_datatype_hook && is_tsql_rowversion_or_timestamp_datatype_hook(att->atttypid))
cstate->rv_index = attnum - 1;

/* Use default value if one exists */
if (defexpr != NULL)
{
Expand Down
1 change: 1 addition & 0 deletions contrib/babelfishpg_tsql/src/pltsql_bulkcopy.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ typedef struct BulkCopyStateData
List *range_table;
int seq_index; /* index for an identity column */
Oid seqid; /* oid of the sequence for an identity column */
int rv_index; /* index for a rowversion datatype column */

} BulkCopyStateData;
typedef struct BulkCopyStateData *BulkCopyState;
Expand Down
4 changes: 2 additions & 2 deletions contrib/babelfishpg_tsql/src/procedures.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ static char *sp_describe_first_result_set_query(char *viewName)
"CAST(t3.\"ORDINAL_POSITION\" AS int) AS column_ordinal, "
"CAST(t3.\"COLUMN_NAME\" AS sys.sysname) AS name, "
"case "
"when t1.is_nullable = \'YES\' then CAST(1 AS sys.bit) "
"when t1.is_nullable = \'YES\' AND t3.\"DATA_TYPE\" <> \'timestamp\' then CAST(1 AS sys.bit) "
"else CAST(0 AS sys.bit) "
"end as is_nullable, "
"t4.system_type_id::int as system_type_id, "
Expand Down Expand Up @@ -313,7 +313,7 @@ static char *sp_describe_first_result_set_query(char *viewName)
"end as is_identity_column, "
"CAST(NULL as sys.bit) as is_part_of_unique_key, " /* pg_constraint */
"case "
"when t1.is_updatable = \'YES\' AND t1.is_generated = \'NEVER\' AND t1.is_identity = \'NO\' then CAST(1 AS sys.bit) "
"when t1.is_updatable = \'YES\' AND t1.is_generated = \'NEVER\' AND t1.is_identity = \'NO\' AND t3.\"DATA_TYPE\" <> \'timestamp\' then CAST(1 AS sys.bit) "
"else CAST(0 AS sys.bit) "
"end as is_updateable, "
"case "
Expand Down
18 changes: 18 additions & 0 deletions test/JDBC/expected/14_3__preparation__get_tds_id-vu-prepare.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CREATE PROCEDURE get_tds_id_proc
AS
SELECT get_tds_id('timestamp') as rv;
GO

CREATE FUNCTION get_tds_id_func(@a sys.varchar(50))
RETURNS INT
AS
BEGIN
DECLARE @b int;
SET @b = (SELECT get_tds_id(@a) as rv);
RETURN @b;
END
GO

CREATE VIEW get_tds_id_view AS
SELECT * FROM get_tds_id('timestamp') AS rv
GO
18 changes: 18 additions & 0 deletions test/JDBC/expected/14_5__preparation__get_tds_id-vu-prepare.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CREATE PROCEDURE get_tds_id_proc
AS
SELECT get_tds_id('timestamp') as rv;
GO

CREATE FUNCTION get_tds_id_func(@a sys.varchar(50))
RETURNS INT
AS
BEGIN
DECLARE @b int;
SET @b = (SELECT get_tds_id(@a) as rv);
RETURN @b;
END
GO

CREATE VIEW get_tds_id_view AS
SELECT * FROM get_tds_id('timestamp') AS rv
GO
8 changes: 8 additions & 0 deletions test/JDBC/expected/get_tds_id-vu-cleanup.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DROP PROCEDURE get_tds_id_proc;
GO

DROP FUNCTION get_tds_id_func;
GO

DROP VIEW get_tds_id_view;
GO
18 changes: 18 additions & 0 deletions test/JDBC/expected/get_tds_id-vu-prepare.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CREATE PROCEDURE get_tds_id_proc
AS
SELECT get_tds_id('timestamp') as rv;
GO

CREATE FUNCTION get_tds_id_func(@a sys.varchar(50))
RETURNS INT
AS
BEGIN
DECLARE @b int;
SET @b = (SELECT get_tds_id(@a) as rv);
RETURN @b;
END
GO

CREATE VIEW get_tds_id_view AS
SELECT * FROM get_tds_id('timestamp') AS rv
GO
32 changes: 32 additions & 0 deletions test/JDBC/expected/get_tds_id-vu-verify.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
EXEC get_tds_id_proc;
GO
~~START~~
int
173
~~END~~


SELECT get_tds_id_func('timestamp') as rv;
GO
~~START~~
int
173
~~END~~


SELECT get_tds_id_func('random') as rv;
GO
~~START~~
int
0
~~END~~


-- for minor version upgrade this view will use previous version of the get_tds_id function
SELECT * FROM get_tds_id_view;
GO
~~START~~
int
173
~~END~~

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DROP PROCEDURE get_tds_id_proc;
GO

DROP FUNCTION get_tds_id_func;
GO

DROP VIEW get_tds_id_view;
GO
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
EXEC get_tds_id_proc;
GO
~~START~~
int
173
~~END~~


SELECT get_tds_id_func('timestamp') as rv;
GO
~~START~~
int
173
~~END~~


SELECT get_tds_id_func('random') as rv;
GO
~~START~~
int
0
~~END~~


-- for minor version upgrade this view will use previous version of the get_tds_id function
SELECT * FROM get_tds_id_view;
GO
~~START~~
int
0
~~END~~

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DROP PROCEDURE get_tds_id_proc;
GO

DROP FUNCTION get_tds_id_func;
GO

DROP VIEW get_tds_id_view;
GO
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
EXEC get_tds_id_proc;
GO
~~START~~
int
173
~~END~~


SELECT get_tds_id_func('timestamp') as rv;
GO
~~START~~
int
173
~~END~~


SELECT get_tds_id_func('random') as rv;
GO
~~START~~
int
0
~~END~~


-- for minor version upgrade this view will use previous version of the get_tds_id function
SELECT * FROM get_tds_id_view;
GO
~~START~~
int
0
~~END~~

8 changes: 8 additions & 0 deletions test/JDBC/input/get_tds_id-vu-cleanup.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DROP PROCEDURE get_tds_id_proc;
GO

DROP FUNCTION get_tds_id_func;
GO

DROP VIEW get_tds_id_view;
GO
18 changes: 18 additions & 0 deletions test/JDBC/input/get_tds_id-vu-prepare.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CREATE PROCEDURE get_tds_id_proc
AS
SELECT get_tds_id('timestamp') as rv;
GO

CREATE FUNCTION get_tds_id_func(@a sys.varchar(50))
RETURNS INT
AS
BEGIN
DECLARE @b int;
SET @b = (SELECT get_tds_id(@a) as rv);
RETURN @b;
END
GO

CREATE VIEW get_tds_id_view AS
SELECT * FROM get_tds_id('timestamp') AS rv
GO
12 changes: 12 additions & 0 deletions test/JDBC/input/get_tds_id-vu-verify.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
EXEC get_tds_id_proc;
GO

SELECT get_tds_id_func('timestamp') as rv;
GO

SELECT get_tds_id_func('random') as rv;
GO

-- for minor version upgrade this view will use previous version of the get_tds_id function
SELECT * FROM get_tds_id_view;
GO
18 changes: 18 additions & 0 deletions test/JDBC/upgrade/14_3/preparation/get_tds_id-vu-prepare.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CREATE PROCEDURE get_tds_id_proc
AS
SELECT get_tds_id('timestamp') as rv;
GO

CREATE FUNCTION get_tds_id_func(@a sys.varchar(50))
RETURNS INT
AS
BEGIN
DECLARE @b int;
SET @b = (SELECT get_tds_id(@a) as rv);
RETURN @b;
END
GO

CREATE VIEW get_tds_id_view AS
SELECT * FROM get_tds_id('timestamp') AS rv
GO
Loading

0 comments on commit 0d522ce

Please sign in to comment.