Skip to content

Commit

Permalink
fix insert exec with type cast (babelfish-for-postgresql#2017)
Browse files Browse the repository at this point in the history
Previously insert exec implement didn't consider the type cast during execution, this fix has add a implicit type cast between insert execution and exec execution if the type is mismatched.

Engine pr : babelfish-for-postgresql/postgresql_modified_for_babelfish#256

Task: BABEL-2999, BABEL-4426
Signed-off-by: Zhibai Song <[email protected]>
  • Loading branch information
forestkeeper authored and staticlibs committed Mar 14, 2024
1 parent abaa687 commit 8a06e90
Show file tree
Hide file tree
Showing 28 changed files with 1,397 additions and 2 deletions.
14 changes: 14 additions & 0 deletions contrib/babelfishpg_tsql/src/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ static void pltsql_ExecutorEnd(QueryDesc *queryDesc);
static bool plsql_TriggerRecursiveCheck(ResultRelInfo *resultRelInfo);
static bool bbf_check_rowcount_hook(int es_processed);

extern bool called_from_tsql_insert_exec();
extern Datum pltsql_exec_tsql_cast_value(Datum value, bool *isnull,
Oid valtype, int32 valtypmod,
Oid reqtype, int32 reqtypmod);

/*****************************************
* Replication Hooks
*****************************************/
Expand Down Expand Up @@ -217,6 +222,8 @@ static table_variable_satisfies_update_hook_type prev_table_variable_satisfies_u
static table_variable_satisfies_vacuum_hook_type prev_table_variable_satisfies_vacuum = NULL;
static table_variable_satisfies_vacuum_horizon_hook_type prev_table_variable_satisfies_vacuum_horizon = NULL;
static drop_relation_refcnt_hook_type prev_drop_relation_refcnt_hook = NULL;
static called_from_tsql_insert_exec_hook_type pre_called_from_tsql_insert_exec_hook = NULL;
static exec_tsql_cast_value_hook_type pre_exec_tsql_cast_value_hook = NULL;

/*****************************************
* Install / Uninstall
Expand Down Expand Up @@ -367,6 +374,12 @@ InstallExtendedHooks(void)

prev_drop_relation_refcnt_hook = drop_relation_refcnt_hook;
drop_relation_refcnt_hook = pltsql_drop_relation_refcnt_hook;

pre_called_from_tsql_insert_exec_hook = called_from_tsql_insert_exec_hook;
called_from_tsql_insert_exec_hook = called_from_tsql_insert_exec;

pre_exec_tsql_cast_value_hook = exec_tsql_cast_value_hook;
exec_tsql_cast_value_hook = pltsql_exec_tsql_cast_value;
}

void
Expand Down Expand Up @@ -425,6 +438,7 @@ UninstallExtendedHooks(void)
IsToastRelationHook = PrevIsToastRelationHook;
IsToastClassHook = PrevIsToastClassHook;
drop_relation_refcnt_hook = prev_drop_relation_refcnt_hook;
called_from_tsql_insert_exec_hook = pre_called_from_tsql_insert_exec_hook;
}

/*****************************************
Expand Down
18 changes: 17 additions & 1 deletion contrib/babelfishpg_tsql/src/pl_exec-2.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include "funcapi.h"

#include "access/table.h"
#include "access/attmap.h"
#include "catalog/namespace.h"
#include "catalog/pg_attribute.h"
#include "catalog/pg_language.h"
#include "commands/proclang.h"
#include "executor/tstoreReceiver.h"
Expand Down Expand Up @@ -59,6 +61,7 @@ static bool is_char_identstart(char c);
static bool is_char_identpart(char c);

void read_param_def(InlineCodeBlockArgs *args, const char *paramdefstr);
bool called_from_tsql_insert_exec(void);
void cache_inline_args(PLtsql_function *func, InlineCodeBlockArgs *args);
InlineCodeBlockArgs *create_args(int numargs);
InlineCodeBlockArgs *clone_inline_args(InlineCodeBlockArgs *args);
Expand Down Expand Up @@ -96,6 +99,7 @@ extern SPIPlanPtr prepare_stmt_exec(PLtsql_execstate *estate, PLtsql_function *f
extern int sp_prepare_count;

BulkCopyStmt *cstmt = NULL;
bool called_from_tsql_insert_execute = false;

int insert_bulk_rows_per_batch = DEFAULT_INSERT_BULK_ROWS_PER_BATCH;
int insert_bulk_kilobytes_per_batch = DEFAULT_INSERT_BULK_PACKET_SIZE;
Expand Down Expand Up @@ -2846,6 +2850,13 @@ exec_stmt_grantdb(PLtsql_execstate *estate, PLtsql_stmt_grantdb *stmt)
return PLTSQL_RC_OK;
}

bool called_from_tsql_insert_exec()
{
if (sql_dialect != SQL_DIALECT_TSQL)
return false;
return called_from_tsql_insert_execute;
}

/*
* For naked SELECT stmt in INSERT ... EXECUTE, instead of pushing the result to
* the client, we accumulate the result in estate->tuple_store (similar to
Expand All @@ -2869,10 +2880,11 @@ exec_stmt_insert_execute_select(PLtsql_execstate *estate, PLtsql_expr *query)
/* Use eval_mcontext for tuple conversion work */
oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));

called_from_tsql_insert_execute = true;
tupmap = convert_tuples_by_position(portal->tupDesc,
estate->tuple_store_desc,
gettext_noop("structure of query does not match function result type"));

called_from_tsql_insert_execute = false;
while (true)
{
uint64 i;
Expand All @@ -2890,7 +2902,11 @@ exec_stmt_insert_execute_select(PLtsql_execstate *estate, PLtsql_expr *query)
HeapTuple tuple = SPI_tuptable->vals[i];

if (tupmap)
{
called_from_tsql_insert_execute = true;
tuple = execute_attr_map_tuple(tuple, tupmap);
called_from_tsql_insert_execute = false;
}
tuplestore_puttuple(estate->tuple_store, tuple);
if (tupmap)
heap_freetuple(tuple);
Expand Down
13 changes: 13 additions & 0 deletions contrib/babelfishpg_tsql/src/pl_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,9 @@ static Datum exec_cast_value(PLtsql_execstate *estate,
Datum value, bool *isnull,
Oid valtype, int32 valtypmod,
Oid reqtype, int32 reqtypmod);
Datum pltsql_exec_tsql_cast_value(Datum value, bool *isnull,
Oid valtype, int32 valtypmod,
Oid reqtype, int32 reqtypmod);
static pltsql_CastHashEntry *get_cast_hashentry(PLtsql_execstate *estate,
Oid srctype, int32 srctypmod,
Oid dsttype, int32 dsttypmod);
Expand Down Expand Up @@ -10368,3 +10371,13 @@ get_original_query_string(void)
{
return original_query_string;
}

Datum pltsql_exec_tsql_cast_value(Datum value, bool *isnull,
Oid valtype, int32 valtypmod,
Oid reqtype, int32 reqtypmod)
{
return exec_cast_value(get_current_tsql_estate(),
value, isnull,
valtype, valtypmod,
reqtype, reqtypmod);
}
2 changes: 2 additions & 0 deletions contrib/babelfishpg_tsql/src/pl_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -4247,6 +4247,7 @@ pltsql_inline_handler(PG_FUNCTION_ARGS)
rsinfo.isDone = ExprSingleResult;
rsinfo.setResult = NULL;
rsinfo.setDesc = NULL;
ReleaseTupleDesc(reldesc);
}

/* And run the function */
Expand Down Expand Up @@ -4313,6 +4314,7 @@ pltsql_inline_handler(PG_FUNCTION_ARGS)
dest->receiveSlot(slot, dest);
ExecClearTuple(slot);
}
ReleaseTupleDesc(rsinfo.expectedDesc);
ExecDropSingleTupleTableSlot(slot);
}

Expand Down
29 changes: 29 additions & 0 deletions test/JDBC/expected/BABEL-2999-vu-cleanup.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
drop table if exists t2_BABEL2999;
GO

drop table t1_BABEL2999;
GO

drop table t3_BABEL2999;
GO

drop table t3_BABEL2999_2;
GO

drop procedure p1_BABEL2999;
GO

drop procedure p2_BABEL2999
GO

drop procedure p3_BABEL2999
GO

drop table t4_BABEL2999;
GO

drop table t5_BABEL2999;
GO

drop table t6_BABEL2999
GO
32 changes: 32 additions & 0 deletions test/JDBC/expected/BABEL-2999-vu-prepare.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
drop table if exists t1_BABEL2999;
GO

create table t1_BABEL2999(b varchar(10));
GO

create table t2_BABEL2999(b int);
GO

create table t3_BABEL2999(b varchar);
GO

create procedure p1_BABEL2999 as select 'abc';
GO

create procedure p2_BABEL2999 as select 555;
GO

create table t3_BABEL2999_2(a int, b datetime, c varchar(20))
GO

create procedure p3_BABEL2999 as select '123', 123, 123;
GO

create table t4_BABEL2999( a binary(30), b varbinary(30), c varchar(30), d datetime, e smalldatetime)
GO

create table t5_BABEL2999( a decimal, b numeric)
GO

create table t6_BABEL2999( a int, b tinyint, c smallint)
GO
Loading

0 comments on commit 8a06e90

Please sign in to comment.