mirror of
https://git.postgresql.org/git/postgresql.git
synced 2026-02-12 09:27:04 +08:00
After binding a statement to a connection with DECLARE STATEMENT the connection was still not used for DEALLOCATE and DESCRIBE statements. This patch fixes that, adds a missing warning and cleans up the code. Author: Hayato Kuroda Reviewed-by: Kyotaro Horiguchi, Michael Paquier Discussion: https://postgr.es/m/TYAPR01MB5866BA57688DF2770E2F95C6F5069%40TYAPR01MB5866.jpnprd01.prod.outlook.com
238 lines
5.8 KiB
Plaintext
238 lines
5.8 KiB
Plaintext
#include <locale.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
EXEC SQL WHENEVER SQLERROR SQLPRINT;
|
|
|
|
EXEC SQL INCLUDE sqlca;
|
|
EXEC SQL INCLUDE ../regression;
|
|
|
|
#define ARRAY_SIZE 2
|
|
|
|
void execute_test(void);
|
|
void commitTable(void);
|
|
void reset(void);
|
|
void printResult(char *tc_name, int loop);
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
int f1[ARRAY_SIZE];
|
|
int f2[ARRAY_SIZE];
|
|
char f3[ARRAY_SIZE][20];
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
int main(void)
|
|
{
|
|
setlocale(LC_ALL, "C");
|
|
|
|
ECPGdebug(1, stderr);
|
|
|
|
EXEC SQL CONNECT TO REGRESSDB1 AS con1;
|
|
EXEC SQL CONNECT TO REGRESSDB2 AS con2;
|
|
|
|
EXEC SQL AT con1 CREATE TABLE source(f1 integer, f2 integer, f3 varchar(20));
|
|
EXEC SQL AT con2 CREATE TABLE source(f1 integer, f2 integer, f3 varchar(20));
|
|
|
|
EXEC SQL AT con1 INSERT INTO source VALUES(1, 10, 'db on con1');
|
|
EXEC SQL AT con1 INSERT INTO source VALUES(2, 20, 'db on con1');
|
|
|
|
EXEC SQL AT con2 INSERT INTO source VALUES(1, 10, 'db on con2');
|
|
EXEC SQL AT con2 INSERT INTO source VALUES(2, 20, 'db on con2');
|
|
|
|
commitTable();
|
|
|
|
execute_test();
|
|
|
|
EXEC SQL AT con1 DROP TABLE IF EXISTS source;
|
|
EXEC SQL AT con2 DROP TABLE IF EXISTS source;
|
|
|
|
commitTable();
|
|
|
|
EXEC SQL DISCONNECT ALL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* default connection: con2
|
|
* Non-default connection: con1
|
|
*
|
|
*/
|
|
void execute_test(void)
|
|
{
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
int i, count, length;
|
|
char *selectString = "SELECT f1,f2,f3 FROM source";
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
/*
|
|
* testcase1. using DECLARE STATEMENT without using AT clause,
|
|
* using PREPARE and CURSOR statement without using AT clause
|
|
*/
|
|
reset();
|
|
|
|
EXEC SQL DECLARE stmt_1 STATEMENT;
|
|
EXEC SQL PREPARE stmt_1 FROM :selectString;
|
|
EXEC SQL DECLARE cur_1 CURSOR FOR stmt_1;
|
|
EXEC SQL OPEN cur_1;
|
|
|
|
EXEC SQL WHENEVER NOT FOUND DO BREAK;
|
|
i = 0;
|
|
while (1)
|
|
{
|
|
EXEC SQL FETCH cur_1 INTO :f1[i], :f2[i], :f3[i];
|
|
i++;
|
|
}
|
|
EXEC SQL CLOSE cur_1;
|
|
EXEC SQL DEALLOCATE PREPARE stmt_1;
|
|
EXEC SQL WHENEVER NOT FOUND CONTINUE;
|
|
|
|
printResult("testcase1", 2);
|
|
|
|
|
|
/*
|
|
* testcase2. using DECLARE STATEMENT at con1,
|
|
* using PREPARE and CURSOR statement without using AT clause
|
|
*/
|
|
reset();
|
|
|
|
EXEC SQL AT con1 DECLARE stmt_2 STATEMENT;
|
|
EXEC SQL PREPARE stmt_2 FROM :selectString;
|
|
EXEC SQL DECLARE cur_2 CURSOR FOR stmt_2;
|
|
EXEC SQL OPEN cur_2;
|
|
|
|
EXEC SQL WHENEVER NOT FOUND DO BREAK;
|
|
i = 0;
|
|
while (1)
|
|
{
|
|
EXEC SQL FETCH cur_2 INTO :f1[i], :f2[i], :f3[i];
|
|
i++;
|
|
}
|
|
EXEC SQL CLOSE cur_2;
|
|
EXEC SQL DEALLOCATE PREPARE stmt_2;
|
|
EXEC SQL WHENEVER NOT FOUND CONTINUE;
|
|
|
|
printResult("testcase2", 2);
|
|
|
|
/*
|
|
* testcase3. using DECLARE STATEMENT at con1,
|
|
* using PREPARE and CURSOR statement at con2
|
|
*/
|
|
reset();
|
|
|
|
EXEC SQL AT con1 DECLARE stmt_3 STATEMENT;
|
|
EXEC SQL AT con2 PREPARE stmt_3 FROM :selectString;
|
|
EXEC SQL AT con2 DECLARE cur_3 CURSOR FOR stmt_3;
|
|
EXEC SQL AT con2 OPEN cur_3;
|
|
|
|
EXEC SQL WHENEVER NOT FOUND DO BREAK;
|
|
i = 0;
|
|
while (1)
|
|
{
|
|
EXEC SQL AT con2 FETCH cur_3 INTO :f1[i], :f2[i], :f3[i];
|
|
i++;
|
|
}
|
|
EXEC SQL AT con2 CLOSE cur_3;
|
|
EXEC SQL AT con2 DEALLOCATE PREPARE stmt_3;
|
|
EXEC SQL WHENEVER NOT FOUND CONTINUE;
|
|
|
|
printResult("testcase3", 2);
|
|
|
|
|
|
/*
|
|
* testcase4. using DECLARE STATEMENT without using AT clause,
|
|
* using PREPARE and CURSOR statement at con2
|
|
*/
|
|
reset();
|
|
|
|
EXEC SQL DECLARE stmt_4 STATEMENT;
|
|
EXEC SQL AT con2 PREPARE stmt_4 FROM :selectString;
|
|
EXEC SQL AT con2 DECLARE cur_4 CURSOR FOR stmt_4;
|
|
EXEC SQL AT con2 OPEN cur_4;
|
|
|
|
EXEC SQL WHENEVER NOT FOUND DO BREAK;
|
|
i = 0;
|
|
while (1)
|
|
{
|
|
EXEC SQL AT con2 FETCH cur_4 INTO :f1[i], :f2[i], :f3[i];
|
|
i++;
|
|
}
|
|
EXEC SQL AT con2 CLOSE cur_4;
|
|
EXEC SQL AT con2 DEALLOCATE PREPARE stmt_4;
|
|
EXEC SQL WHENEVER NOT FOUND CONTINUE;
|
|
|
|
printResult("testcase4", 2);
|
|
|
|
/*
|
|
* testcase5. using DECLARE STATEMENT without using AT clause,
|
|
* using PREPARE and EXECUTE statement without using AT clause
|
|
*/
|
|
reset();
|
|
|
|
EXEC SQL DECLARE stmt_5 STATEMENT;
|
|
EXEC SQL PREPARE stmt_5 FROM :selectString;
|
|
EXEC SQL EXECUTE stmt_5 INTO :f1, :f2, :f3;
|
|
|
|
EXEC SQL DEALLOCATE PREPARE stmt_5;
|
|
|
|
printResult("testcase5", 2);
|
|
|
|
/*
|
|
* DESCRIBE statement is also supported.
|
|
*/
|
|
EXEC SQL AT con1 DECLARE stmt_desc STATEMENT;
|
|
EXEC SQL PREPARE stmt_desc FROM :selectString;
|
|
EXEC SQL DECLARE cur_desc CURSOR FOR stmt_desc;
|
|
EXEC SQL OPEN cur_desc;
|
|
|
|
/* descriptor can be used for describe statement */
|
|
EXEC SQL AT con1 ALLOCATE DESCRIPTOR desc_for_describe;
|
|
EXEC SQL DESCRIBE stmt_desc INTO SQL DESCRIPTOR desc_for_describe;
|
|
|
|
EXEC SQL AT con1 GET DESCRIPTOR desc_for_describe :count = COUNT;
|
|
EXEC SQL AT con1 GET DESCRIPTOR desc_for_describe VALUE 3 :length = LENGTH;
|
|
|
|
EXEC SQL AT con1 DEALLOCATE DESCRIPTOR desc_for_describe;
|
|
|
|
/* for fetch statement */
|
|
EXEC SQL AT con1 ALLOCATE DESCRIPTOR desc_for_fetch;
|
|
EXEC SQL FETCH cur_desc INTO SQL DESCRIPTOR desc_for_fetch;
|
|
|
|
EXEC SQL AT con1 GET DESCRIPTOR desc_for_fetch VALUE 3 :f3[0] = DATA;
|
|
|
|
EXEC SQL AT con1 DEALLOCATE DESCRIPTOR desc_for_fetch;
|
|
EXEC SQL CLOSE cur_desc;
|
|
EXEC SQL DEALLOCATE stmt_desc;
|
|
|
|
printf("****descriptor results****\n");
|
|
printf("count: %d, length: %d, data: %s\n", count, length, f3[0]);
|
|
}
|
|
|
|
void commitTable()
|
|
{
|
|
EXEC SQL AT con1 COMMIT;
|
|
EXEC SQL AT con2 COMMIT;
|
|
}
|
|
|
|
/*
|
|
* reset all the output variables
|
|
*/
|
|
void reset()
|
|
{
|
|
memset(f1, 0, sizeof(f1));
|
|
memset(f2, 0, sizeof(f2));
|
|
memset(f3, 0, sizeof(f3));
|
|
}
|
|
|
|
void printResult(char *tc_name, int loop)
|
|
{
|
|
int i;
|
|
|
|
if (tc_name)
|
|
printf("****%s test results:****\n", tc_name);
|
|
|
|
for (i = 0; i < loop; i++)
|
|
printf("f1=%d, f2=%d, f3=%s\n", f1[i], f2[i], f3[i]);
|
|
|
|
printf("\n");
|
|
}
|