Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions contrib/babelfishpg_tsql/src/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -1449,6 +1449,9 @@ execute_sp_cursoropen_common(int *stmt_handle, int *cursor_handle, const char *s
Portal portal;
MemoryContext oldcontext;
MemoryContext savedPortalCxt;
PLtsql_stmt_execsql *parse_result;
PLtsql_function *func;
char *stmt_copy;

/*
* Connect to SPI manager. should be handled in the same way with
Expand All @@ -1468,6 +1471,42 @@ execute_sp_cursoropen_common(int *stmt_handle, int *cursor_handle, const char *s

if (prepare)
{
/*
* This entire block is to parse the statement by antlr and use the resultant
* statement to sent to Postgres cursor execution. This is necessary in some use case,
* for example when we have PostgreSQL reversed keywords in query which is valid in TSQL.
* Antlr parser will add the quotes at necessary places in query so that Postgres engine
* can resolve this query correctly.
*/
if (stmt)
{
/* Copy the original statement, because we don't want to use the resultant query in every case. */
stmt_copy = pstrdup(stmt);
/* Send to antlr parser */
func = pltsql_compile_inline(stmt_copy, NULL);

/*
* Check the node list of type PLtsql_stmt_type. Cursor only support single statement.
* If there are more than 1 statement we will through the error. func->action-body
* returned by pltsql_compile_inline contains two default nodes, PLTSQL_STMT_INIT being first
* and PLTSQL_STMT_RETURN being last. So total number of nodes should be 3 for cursor. Actual
* query statement will be at second position of type PLTSQL_STMT_EXECSQL.

* This is defensive code, where we only reassign the stmt variable to parsed query,
* if the cmd_type is PLTSQL_STMT_EXECSQL. There might be other types of cmd_type like
* PLTSQL_STMT_EXECSQL (for procedures), for them we will keep the old behavior.
*/
if((( (PLtsql_stmt *) lsecond(func->action->body))->cmd_type == PLTSQL_STMT_EXECSQL)
&& list_length(func->action->body) == 3)
{
parse_result = (PLtsql_stmt_execsql *) lsecond(func->action->body);
stmt = pstrdup(parse_result->sqlstmt->query);
}

/*Free up function memory as this is not needed anymore */
pltsql_free_function_memory(func);
}

/* prepare plan and insert a cursor entry */
plan = SPI_prepare_cursor(stmt, nBindParams, boundParamsOidList, cursor_options);
if (plan == NULL)
Expand Down
38 changes: 38 additions & 0 deletions test/JDBC/expected/TestCursorFetchNext.out
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,44 @@ int#!#smallint#!#bigint#!#tinyint#!#bit
#cursor#!#fetch#!#next
#cursor#!#fetch#!#afterlast
#cursor#!#fetch#!#next
cursor#!#close
~~SUCCESS~~
cursor#!#open#!#SELECT a year, b month, c quarter FROM test_cursors_fetch_next#!#TYPE_SCROLL_INSENSITIVE#!#CONCUR_READ_ONLY#!#CLOSE_CURSORS_AT_COMMIT
~~SUCCESS~~
cursor#!#fetch#!#next
~~START~~
int#!#smallint#!#bigint
0#!#0#!#0
~~END~~

cursor#!#fetch#!#first
~~START~~
int#!#smallint#!#bigint
0#!#0#!#0
~~END~~

cursor#!#fetch#!#next
~~START~~
int#!#smallint#!#bigint
<NULL>#!#<NULL>#!#<NULL>
~~END~~

cursor#!#fetch#!#last
~~START~~
int#!#smallint#!#bigint
211234#!#9780#!#891372401
~~END~~

cursor#!#close
~~SUCCESS~~
cursor#!#open#!#DECLARE @var INT; select @var = 5; select @var + 1;#!#CONCUR_READ_ONLY#!#CLOSE_CURSORS_AT_COMMIT
~~SUCCESS~~
cursor#!#fetch#!#next
~~START~~
int
6
~~END~~

cursor#!#close
~~SUCCESS~~
DROP TABLE test_cursors_fetch_next
Expand Down
32 changes: 32 additions & 0 deletions test/JDBC/expected/TestCursorPrepExecFetchNext.out
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,38 @@ int#!#smallint#!#bigint#!#tinyint#!#bit
#cursor#!#fetch#!#next
#cursor#!#fetch#!#afterlast
#cursor#!#fetch#!#next
cursor#!#close
~~SUCCESS~~
cursor#!#open#!#prepst#!#SELECT a year, b month, c quarter from test_cursor_prep_exec_fetch_next#!#TYPE_SCROLL_INSENSITIVE#!#CONCUR_READ_ONLY#!#CLOSE_CURSORS_AT_COMMIT
~~SUCCESS~~
cursor#!#fetch#!#next
~~START~~
int#!#smallint#!#bigint
0#!#0#!#0
~~END~~

cursor#!#fetch#!#first
~~START~~
int#!#smallint#!#bigint
0#!#0#!#0
~~END~~

cursor#!#fetch#!#next
~~START~~
int#!#smallint#!#bigint
<NULL>#!#<NULL>#!#<NULL>
~~END~~

cursor#!#close
~~SUCCESS~~
cursor#!#open#!#DECLARE @var INT; select @var = 5; select @var + 1;#!#CONCUR_READ_ONLY#!#CLOSE_CURSORS_AT_COMMIT
~~SUCCESS~~
cursor#!#fetch#!#next
~~START~~
int
6
~~END~~

cursor#!#close
~~SUCCESS~~
DROP TABLE test_cursor_prep_exec_fetch_next
Expand Down
9 changes: 9 additions & 0 deletions test/JDBC/input/cursors/TestCursorFetchNext.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ cursor#!#fetch#!#next
#cursor#!#fetch#!#afterlast
#cursor#!#fetch#!#next
cursor#!#close
cursor#!#open#!#SELECT a year, b month, c quarter FROM test_cursors_fetch_next#!#TYPE_SCROLL_INSENSITIVE#!#CONCUR_READ_ONLY#!#CLOSE_CURSORS_AT_COMMIT
cursor#!#fetch#!#next
cursor#!#fetch#!#first
cursor#!#fetch#!#next
cursor#!#fetch#!#last
cursor#!#close
cursor#!#open#!#DECLARE @var INT; select @var = 5; select @var + 1;#!#CONCUR_READ_ONLY#!#CLOSE_CURSORS_AT_COMMIT
cursor#!#fetch#!#next
cursor#!#close
DROP TABLE test_cursors_fetch_next

CREATE TABLE test_cursors_fetch_next(a CHAR(30), b VARCHAR(30), c NCHAR(30), d NVARCHAR(30));
Expand Down
8 changes: 8 additions & 0 deletions test/JDBC/input/cursors/TestCursorPrepExecFetchNext.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ cursor#!#fetch#!#next
#cursor#!#fetch#!#afterlast
#cursor#!#fetch#!#next
cursor#!#close
cursor#!#open#!#prepst#!#SELECT a year, b month, c quarter from test_cursor_prep_exec_fetch_next#!#TYPE_SCROLL_INSENSITIVE#!#CONCUR_READ_ONLY#!#CLOSE_CURSORS_AT_COMMIT
cursor#!#fetch#!#next
cursor#!#fetch#!#first
cursor#!#fetch#!#next
cursor#!#close
cursor#!#open#!#DECLARE @var INT; select @var = 5; select @var + 1;#!#CONCUR_READ_ONLY#!#CLOSE_CURSORS_AT_COMMIT
cursor#!#fetch#!#next
cursor#!#close
DROP TABLE test_cursor_prep_exec_fetch_next

CREATE TABLE test_cursor_prep_exec_fetch_next(a CHAR(30), b VARCHAR(30), c NCHAR(30), d NVARCHAR(30));
Expand Down
Loading