mirror of
https://github.com/postgres/postgres.git
synced 2025-05-03 22:24:49 +03:00
Add DECLARE STATEMENT command to ECPG
This command declares a SQL identifier for a SQL statement to be used in other embedded SQL statements. The identifier is linked to a connection. Author: Hayato Kuroda <kuroda.hayato@fujitsu.com> Reviewed-by: Shawn Wang <shawn.wang.pg@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/TY2PR01MB24438A52DB04E71D0E501452F5630@TY2PR01MB2443.jpnprd01.prod.outlook.com
This commit is contained in:
parent
37c99d304d
commit
ad8305a43d
@ -278,7 +278,7 @@ EXEC SQL CONNECT TO :target USER :user USING :passwd;
|
|||||||
SQL statements in embedded SQL programs are by default executed on
|
SQL statements in embedded SQL programs are by default executed on
|
||||||
the current connection, that is, the most recently opened one. If
|
the current connection, that is, the most recently opened one. If
|
||||||
an application needs to manage multiple connections, then there are
|
an application needs to manage multiple connections, then there are
|
||||||
two ways to handle this.
|
three ways to handle this.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -350,6 +350,46 @@ main()
|
|||||||
current=testdb3 (should be testdb3)
|
current=testdb3 (should be testdb3)
|
||||||
current=testdb2 (should be testdb2)
|
current=testdb2 (should be testdb2)
|
||||||
current=testdb1 (should be testdb1)
|
current=testdb1 (should be testdb1)
|
||||||
|
</screen>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The third option is to declare sql identifier linked to
|
||||||
|
the connection, for example:
|
||||||
|
<programlisting>
|
||||||
|
EXEC SQL AT <replaceable>connection-name</replaceable> DECLARE <replaceable>statement-name</replaceable> STATEMENT;
|
||||||
|
EXEC SQL PREPARE <replaceable>statement-name</replaceable> FROM :<replaceable>dyn-string</replaceable>;
|
||||||
|
</programlisting>
|
||||||
|
Once you link a sql identifier to a connection, you execute a dynamic SQL
|
||||||
|
without AT clause. Note that this option behaves like preprocessor directives,
|
||||||
|
therefore the link is enabled only in the file.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Here is an example program using this option:
|
||||||
|
<programlisting><![CDATA[
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
EXEC SQL BEGIN DECLARE SECTION;
|
||||||
|
char dbname[128];
|
||||||
|
char *dym_sql = "SELECT current_database()";
|
||||||
|
EXEC SQL END DECLARE SECTION;
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
EXEC SQL CONNECT TO postgres AS con1;
|
||||||
|
EXEC SQL CONNECT TO testdb AS con2;
|
||||||
|
EXEC SQL AT con1 DECLARE stmt STATEMENT;
|
||||||
|
EXEC SQL PREPARE stmt FROM :dym_sql;
|
||||||
|
EXEC SQL EXECUTE stmt INTO :dbname;
|
||||||
|
printf("%s\n", dbname);
|
||||||
|
|
||||||
|
EXEC SQL DISCONNECT ALL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
]]></programlisting>
|
||||||
|
|
||||||
|
This example would produce this output, even if the default connection is testdb:
|
||||||
|
<screen>
|
||||||
|
postgres
|
||||||
</screen>
|
</screen>
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
@ -6855,6 +6895,104 @@ EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
|
|||||||
</refsect1>
|
</refsect1>
|
||||||
</refentry>
|
</refentry>
|
||||||
|
|
||||||
|
<refentry id="ecpg-sql-declare-statement">
|
||||||
|
<refnamediv>
|
||||||
|
<refname>DECLARE STATEMENT</refname>
|
||||||
|
<refpurpose>declare SQL statement identifier</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<synopsis>
|
||||||
|
EXEC SQL [ AT <replaceable class="parameter">connection_name</replaceable> ] DECLARE <replaceable class="parameter">statement_name</replaceable> STATEMENT
|
||||||
|
</synopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<command>DECLARE STATEMENT</command> declares SQL statement identifier.
|
||||||
|
SQL statement identifier can be associated with the connection.
|
||||||
|
When the identifier is used by dynamic SQL statements, these SQLs are executed
|
||||||
|
by using the associated connection.
|
||||||
|
The namespace of the declaration is the precompile unit, and multiple declarations to
|
||||||
|
the same SQL statement identifier is not allowed.
|
||||||
|
|
||||||
|
Note that if the precompiler run in the Informix compatibility mode and some SQL statement
|
||||||
|
is declared, "database" can not be used as a cursor name.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Parameters</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">connection_name</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A database connection name established by the <command>CONNECT</command> command.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
AT clause can be omitted, but such statement has no meaning.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">statement_name</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The name of a SQL statement identifier, either as an SQL identifier or a host variable.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
<para>
|
||||||
|
This association is valid only if the declaration is physically placed on top of a dynamic statement.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Examples</title>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
EXEC SQL CONNECT TO postgres AS con1;
|
||||||
|
EXEC SQL AT con1 DECLARE sql_stmt STATEMENT;
|
||||||
|
EXEC SQL DECLARE cursor_name CURSOR FOR sql_stmt;
|
||||||
|
EXEC SQL PREPARE sql_stmt FROM :dyn_string;
|
||||||
|
EXEC SQL OPEN cursor_name;
|
||||||
|
EXEC SQL FETCH cursor_name INTO :column1;
|
||||||
|
EXEC SQL CLOSE cursor_name;
|
||||||
|
</programlisting>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Compatibility</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<command>DECLARE STATEMENT</command> is a extension of the SQL standard,
|
||||||
|
but can be used in famous DBMSs.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
|
||||||
|
<simplelist type="inline">
|
||||||
|
<member><xref linkend="ecpg-sql-connect"/></member>
|
||||||
|
<member><xref linkend="ecpg-sql-declare"/></member>
|
||||||
|
<member><xref linkend="ecpg-sql-open"/></member>
|
||||||
|
</simplelist>
|
||||||
|
</refsect1>
|
||||||
|
</refentry>
|
||||||
|
|
||||||
<refentry id="ecpg-sql-describe">
|
<refentry id="ecpg-sql-describe">
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>DESCRIBE</refname>
|
<refname>DESCRIBE</refname>
|
||||||
|
@ -33,6 +33,7 @@ ECPG: stmtUpdateStmt block
|
|||||||
{ output_statement($1, 1, ECPGst_prepnormal); }
|
{ output_statement($1, 1, ECPGst_prepnormal); }
|
||||||
ECPG: stmtExecuteStmt block
|
ECPG: stmtExecuteStmt block
|
||||||
{
|
{
|
||||||
|
check_declared_list($1.name);
|
||||||
if ($1.type == NULL || strlen($1.type) == 0)
|
if ($1.type == NULL || strlen($1.type) == 0)
|
||||||
output_statement($1.name, 1, ECPGst_execute);
|
output_statement($1.name, 1, ECPGst_execute);
|
||||||
else
|
else
|
||||||
@ -56,6 +57,7 @@ ECPG: stmtExecuteStmt block
|
|||||||
}
|
}
|
||||||
ECPG: stmtPrepareStmt block
|
ECPG: stmtPrepareStmt block
|
||||||
{
|
{
|
||||||
|
check_declared_list($1.name);
|
||||||
if ($1.type == NULL)
|
if ($1.type == NULL)
|
||||||
output_prepare_statement($1.name, $1.stmt);
|
output_prepare_statement($1.name, $1.stmt);
|
||||||
else if (strlen($1.type) == 0)
|
else if (strlen($1.type) == 0)
|
||||||
@ -104,6 +106,10 @@ ECPG: stmtViewStmt rule
|
|||||||
whenever_action(2);
|
whenever_action(2);
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
|
| ECPGDeclareStmt
|
||||||
|
{
|
||||||
|
output_simple_statement($1, 0);
|
||||||
|
}
|
||||||
| ECPGCursorStmt
|
| ECPGCursorStmt
|
||||||
{
|
{
|
||||||
output_simple_statement($1, (strncmp($1, "ECPGset_var", strlen("ECPGset_var")) == 0) ? 4 : 0);
|
output_simple_statement($1, (strncmp($1, "ECPGset_var", strlen("ECPGset_var")) == 0) ? 4 : 0);
|
||||||
@ -244,14 +250,20 @@ ECPG: var_valueNumericOnly addon
|
|||||||
$1 = mm_strdup("$0");
|
$1 = mm_strdup("$0");
|
||||||
}
|
}
|
||||||
ECPG: fetch_argscursor_name addon
|
ECPG: fetch_argscursor_name addon
|
||||||
add_additional_variables($1, false);
|
struct cursor *ptr = add_additional_variables($1, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
if ($1[0] == ':')
|
if ($1[0] == ':')
|
||||||
{
|
{
|
||||||
free($1);
|
free($1);
|
||||||
$1 = mm_strdup("$0");
|
$1 = mm_strdup("$0");
|
||||||
}
|
}
|
||||||
ECPG: fetch_argsfrom_incursor_name addon
|
ECPG: fetch_argsfrom_incursor_name addon
|
||||||
add_additional_variables($2, false);
|
struct cursor *ptr = add_additional_variables($2, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
if ($2[0] == ':')
|
if ($2[0] == ':')
|
||||||
{
|
{
|
||||||
free($2);
|
free($2);
|
||||||
@ -262,14 +274,20 @@ ECPG: fetch_argsPRIORopt_from_incursor_name addon
|
|||||||
ECPG: fetch_argsFIRST_Popt_from_incursor_name addon
|
ECPG: fetch_argsFIRST_Popt_from_incursor_name addon
|
||||||
ECPG: fetch_argsLAST_Popt_from_incursor_name addon
|
ECPG: fetch_argsLAST_Popt_from_incursor_name addon
|
||||||
ECPG: fetch_argsALLopt_from_incursor_name addon
|
ECPG: fetch_argsALLopt_from_incursor_name addon
|
||||||
add_additional_variables($3, false);
|
struct cursor *ptr = add_additional_variables($3, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
if ($3[0] == ':')
|
if ($3[0] == ':')
|
||||||
{
|
{
|
||||||
free($3);
|
free($3);
|
||||||
$3 = mm_strdup("$0");
|
$3 = mm_strdup("$0");
|
||||||
}
|
}
|
||||||
ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
|
ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
|
||||||
add_additional_variables($3, false);
|
struct cursor *ptr = add_additional_variables($3, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
if ($3[0] == ':')
|
if ($3[0] == ':')
|
||||||
{
|
{
|
||||||
free($3);
|
free($3);
|
||||||
@ -282,7 +300,10 @@ ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
|
|||||||
}
|
}
|
||||||
ECPG: fetch_argsFORWARDALLopt_from_incursor_name addon
|
ECPG: fetch_argsFORWARDALLopt_from_incursor_name addon
|
||||||
ECPG: fetch_argsBACKWARDALLopt_from_incursor_name addon
|
ECPG: fetch_argsBACKWARDALLopt_from_incursor_name addon
|
||||||
add_additional_variables($4, false);
|
struct cursor *ptr = add_additional_variables($4, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
if ($4[0] == ':')
|
if ($4[0] == ':')
|
||||||
{
|
{
|
||||||
free($4);
|
free($4);
|
||||||
@ -292,7 +313,10 @@ ECPG: fetch_argsABSOLUTE_PSignedIconstopt_from_incursor_name addon
|
|||||||
ECPG: fetch_argsRELATIVE_PSignedIconstopt_from_incursor_name addon
|
ECPG: fetch_argsRELATIVE_PSignedIconstopt_from_incursor_name addon
|
||||||
ECPG: fetch_argsFORWARDSignedIconstopt_from_incursor_name addon
|
ECPG: fetch_argsFORWARDSignedIconstopt_from_incursor_name addon
|
||||||
ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
|
ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
|
||||||
add_additional_variables($4, false);
|
struct cursor *ptr = add_additional_variables($4, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
if ($4[0] == ':')
|
if ($4[0] == ':')
|
||||||
{
|
{
|
||||||
free($4);
|
free($4);
|
||||||
@ -348,6 +372,9 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
|
|||||||
char *comment, *c1, *c2;
|
char *comment, *c1, *c2;
|
||||||
int (* strcmp_fn)(const char *, const char *) = (($2[0] == ':' || $2[0] == '"') ? strcmp : pg_strcasecmp);
|
int (* strcmp_fn)(const char *, const char *) = (($2[0] == ':' || $2[0] == '"') ? strcmp : pg_strcasecmp);
|
||||||
|
|
||||||
|
if (INFORMIX_MODE && pg_strcasecmp($2, "database") == 0)
|
||||||
|
mmfatal(PARSE_ERROR, "\"database\" cannot be used as cursor name in INFORMIX mode");
|
||||||
|
|
||||||
for (ptr = cur; ptr != NULL; ptr = ptr->next)
|
for (ptr = cur; ptr != NULL; ptr = ptr->next)
|
||||||
{
|
{
|
||||||
if (strcmp_fn($2, ptr->name) == 0)
|
if (strcmp_fn($2, ptr->name) == 0)
|
||||||
@ -388,6 +415,17 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
|
|||||||
ECPG: ClosePortalStmtCLOSEcursor_name block
|
ECPG: ClosePortalStmtCLOSEcursor_name block
|
||||||
{
|
{
|
||||||
char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : $2;
|
char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : $2;
|
||||||
|
struct cursor *ptr = NULL;
|
||||||
|
for (ptr = cur; ptr != NULL; ptr = ptr -> next)
|
||||||
|
{
|
||||||
|
if (strcmp($2, ptr -> name) == 0)
|
||||||
|
{
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
$$ = cat2_str(mm_strdup("close"), cursor_marker);
|
$$ = cat2_str(mm_strdup("close"), cursor_marker);
|
||||||
}
|
}
|
||||||
ECPG: opt_hold block
|
ECPG: opt_hold block
|
||||||
@ -466,49 +504,73 @@ ECPG: FetchStmtMOVEfetch_args rule
|
|||||||
| FETCH FORWARD cursor_name opt_ecpg_fetch_into
|
| FETCH FORWARD cursor_name opt_ecpg_fetch_into
|
||||||
{
|
{
|
||||||
char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
|
char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
|
||||||
add_additional_variables($3, false);
|
struct cursor *ptr = add_additional_variables($3, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
$$ = cat_str(2, mm_strdup("fetch forward"), cursor_marker);
|
$$ = cat_str(2, mm_strdup("fetch forward"), cursor_marker);
|
||||||
}
|
}
|
||||||
| FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into
|
| FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into
|
||||||
{
|
{
|
||||||
char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
|
char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
|
||||||
add_additional_variables($4, false);
|
struct cursor *ptr = add_additional_variables($4, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
$$ = cat_str(2, mm_strdup("fetch forward from"), cursor_marker);
|
$$ = cat_str(2, mm_strdup("fetch forward from"), cursor_marker);
|
||||||
}
|
}
|
||||||
| FETCH BACKWARD cursor_name opt_ecpg_fetch_into
|
| FETCH BACKWARD cursor_name opt_ecpg_fetch_into
|
||||||
{
|
{
|
||||||
char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
|
char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
|
||||||
add_additional_variables($3, false);
|
struct cursor *ptr = add_additional_variables($3, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
$$ = cat_str(2, mm_strdup("fetch backward"), cursor_marker);
|
$$ = cat_str(2, mm_strdup("fetch backward"), cursor_marker);
|
||||||
}
|
}
|
||||||
| FETCH BACKWARD from_in cursor_name opt_ecpg_fetch_into
|
| FETCH BACKWARD from_in cursor_name opt_ecpg_fetch_into
|
||||||
{
|
{
|
||||||
char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
|
char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
|
||||||
add_additional_variables($4, false);
|
struct cursor *ptr = add_additional_variables($4, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
$$ = cat_str(2, mm_strdup("fetch backward from"), cursor_marker);
|
$$ = cat_str(2, mm_strdup("fetch backward from"), cursor_marker);
|
||||||
}
|
}
|
||||||
| MOVE FORWARD cursor_name
|
| MOVE FORWARD cursor_name
|
||||||
{
|
{
|
||||||
char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
|
char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
|
||||||
add_additional_variables($3, false);
|
struct cursor *ptr = add_additional_variables($3, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
$$ = cat_str(2, mm_strdup("move forward"), cursor_marker);
|
$$ = cat_str(2, mm_strdup("move forward"), cursor_marker);
|
||||||
}
|
}
|
||||||
| MOVE FORWARD from_in cursor_name
|
| MOVE FORWARD from_in cursor_name
|
||||||
{
|
{
|
||||||
char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
|
char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
|
||||||
add_additional_variables($4, false);
|
struct cursor *ptr = add_additional_variables($4, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
$$ = cat_str(2, mm_strdup("move forward from"), cursor_marker);
|
$$ = cat_str(2, mm_strdup("move forward from"), cursor_marker);
|
||||||
}
|
}
|
||||||
| MOVE BACKWARD cursor_name
|
| MOVE BACKWARD cursor_name
|
||||||
{
|
{
|
||||||
char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
|
char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
|
||||||
add_additional_variables($3, false);
|
struct cursor *ptr = add_additional_variables($3, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
$$ = cat_str(2, mm_strdup("move backward"), cursor_marker);
|
$$ = cat_str(2, mm_strdup("move backward"), cursor_marker);
|
||||||
}
|
}
|
||||||
| MOVE BACKWARD from_in cursor_name
|
| MOVE BACKWARD from_in cursor_name
|
||||||
{
|
{
|
||||||
char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
|
char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
|
||||||
add_additional_variables($4, false);
|
struct cursor *ptr = add_additional_variables($4, false);
|
||||||
|
if (ptr -> connection)
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
|
||||||
$$ = cat_str(2, mm_strdup("move backward from"), cursor_marker);
|
$$ = cat_str(2, mm_strdup("move backward from"), cursor_marker);
|
||||||
}
|
}
|
||||||
ECPG: limit_clauseLIMITselect_limit_value','select_offset_value block
|
ECPG: limit_clauseLIMITselect_limit_value','select_offset_value block
|
||||||
|
@ -28,6 +28,7 @@ struct _include_path *include_paths = NULL;
|
|||||||
struct cursor *cur = NULL;
|
struct cursor *cur = NULL;
|
||||||
struct typedefs *types = NULL;
|
struct typedefs *types = NULL;
|
||||||
struct _defines *defines = NULL;
|
struct _defines *defines = NULL;
|
||||||
|
struct declared_list *g_declared_list = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
help(const char *progname)
|
help(const char *progname)
|
||||||
@ -347,6 +348,7 @@ main(int argc, char *const argv[])
|
|||||||
struct cursor *ptr;
|
struct cursor *ptr;
|
||||||
struct _defines *defptr;
|
struct _defines *defptr;
|
||||||
struct typedefs *typeptr;
|
struct typedefs *typeptr;
|
||||||
|
struct declared_list *list;
|
||||||
|
|
||||||
/* remove old cursor definitions if any are still there */
|
/* remove old cursor definitions if any are still there */
|
||||||
for (ptr = cur; ptr != NULL;)
|
for (ptr = cur; ptr != NULL;)
|
||||||
@ -373,6 +375,13 @@ main(int argc, char *const argv[])
|
|||||||
}
|
}
|
||||||
cur = NULL;
|
cur = NULL;
|
||||||
|
|
||||||
|
/* remove old delared statements if any are still there */
|
||||||
|
for (list = g_declared_list; list != NULL;)
|
||||||
|
{
|
||||||
|
struct declared_list *this = list;
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
/* remove non-pertinent old defines as well */
|
/* remove non-pertinent old defines as well */
|
||||||
while (defines && !defines->pertinent)
|
while (defines && !defines->pertinent)
|
||||||
{
|
{
|
||||||
|
@ -64,6 +64,8 @@ static struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, NULL, {NUL
|
|||||||
|
|
||||||
static void vmmerror(int error_code, enum errortype type, const char *error, va_list ap) pg_attribute_printf(3, 0);
|
static void vmmerror(int error_code, enum errortype type, const char *error, va_list ap) pg_attribute_printf(3, 0);
|
||||||
|
|
||||||
|
static bool check_declared_list(const char*);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle parsing errors and warnings
|
* Handle parsing errors and warnings
|
||||||
*/
|
*/
|
||||||
@ -576,6 +578,29 @@ add_typedef(char *name, char *dimension, char *length, enum ECPGttype type_enum,
|
|||||||
types = this;
|
types = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check an SQL identifier is declared or not.
|
||||||
|
* If it is already declared, the global variable
|
||||||
|
* connection will be changed to the related connection.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
check_declared_list(const char *name)
|
||||||
|
{
|
||||||
|
struct declared_list *ptr = NULL;
|
||||||
|
for (ptr = g_declared_list; ptr != NULL; ptr = ptr -> next)
|
||||||
|
{
|
||||||
|
if (strcmp(name, ptr -> name) == 0)
|
||||||
|
{
|
||||||
|
if (ptr -> connection)
|
||||||
|
{
|
||||||
|
connection = mm_strdup(ptr -> connection);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%expect 0
|
%expect 0
|
||||||
|
@ -290,6 +290,42 @@ prepared_name: name
|
|||||||
| char_variable { $$ = $1; }
|
| char_variable { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Declare Statement
|
||||||
|
*/
|
||||||
|
ECPGDeclareStmt: DECLARE prepared_name STATEMENT
|
||||||
|
{
|
||||||
|
struct declared_list *ptr = NULL;
|
||||||
|
/* Check whether the declared name has been defined or not */
|
||||||
|
for (ptr = g_declared_list; ptr != NULL; ptr = ptr->next)
|
||||||
|
{
|
||||||
|
if (strcmp($2, ptr->name) == 0)
|
||||||
|
{
|
||||||
|
/* re-definition is not allowed */
|
||||||
|
mmerror(PARSE_ERROR, ET_ERROR, "declared name %s is already defined", ptr->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a new declared name into the g_declared_list */
|
||||||
|
ptr = NULL;
|
||||||
|
ptr = (struct declared_list *)mm_alloc(sizeof(struct declared_list));
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
/* initial definition */
|
||||||
|
ptr -> name = $2;
|
||||||
|
if (connection)
|
||||||
|
ptr -> connection = mm_strdup(connection);
|
||||||
|
else
|
||||||
|
ptr -> connection = NULL;
|
||||||
|
|
||||||
|
ptr -> next = g_declared_list;
|
||||||
|
g_declared_list = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
$$ = cat_str(3 , mm_strdup("/* declare "), mm_strdup($2), mm_strdup(" as an SQL identifier */"));
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Declare a prepared cursor. The syntax is different from the standard
|
* Declare a prepared cursor. The syntax is different from the standard
|
||||||
* declare statement, so we create a new rule.
|
* declare statement, so we create a new rule.
|
||||||
@ -300,9 +336,14 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
|
|||||||
char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2);
|
char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2);
|
||||||
int (* strcmp_fn)(const char *, const char *) = (($2[0] == ':' || $2[0] == '"') ? strcmp : pg_strcasecmp);
|
int (* strcmp_fn)(const char *, const char *) = (($2[0] == ':' || $2[0] == '"') ? strcmp : pg_strcasecmp);
|
||||||
struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
|
struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
|
||||||
const char *con = connection ? connection : "NULL";
|
|
||||||
char *comment;
|
char *comment;
|
||||||
|
char *con;
|
||||||
|
|
||||||
|
if (INFORMIX_MODE && pg_strcasecmp($2, "database") == 0)
|
||||||
|
mmfatal(PARSE_ERROR, "\"database\" cannot be used as cursor name in INFORMIX mode");
|
||||||
|
|
||||||
|
check_declared_list($7);
|
||||||
|
con = connection ? connection : "NULL";
|
||||||
for (ptr = cur; ptr != NULL; ptr = ptr->next)
|
for (ptr = cur; ptr != NULL; ptr = ptr->next)
|
||||||
{
|
{
|
||||||
if (strcmp_fn($2, ptr->name) == 0)
|
if (strcmp_fn($2, ptr->name) == 0)
|
||||||
@ -321,7 +362,7 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
|
|||||||
this->next = cur;
|
this->next = cur;
|
||||||
this->name = $2;
|
this->name = $2;
|
||||||
this->function = (current_function ? mm_strdup(current_function) : NULL);
|
this->function = (current_function ? mm_strdup(current_function) : NULL);
|
||||||
this->connection = connection;
|
this->connection = connection ? mm_strdup(connection) : NULL;
|
||||||
this->command = cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1"));
|
this->command = cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1"));
|
||||||
this->argsresult = NULL;
|
this->argsresult = NULL;
|
||||||
this->argsresult_oos = NULL;
|
this->argsresult_oos = NULL;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
%type <str> ECPGDeallocateDescr
|
%type <str> ECPGDeallocateDescr
|
||||||
%type <str> ECPGDeclaration
|
%type <str> ECPGDeclaration
|
||||||
%type <str> ECPGDeclare
|
%type <str> ECPGDeclare
|
||||||
|
%type <str> ECPGDeclareStmt
|
||||||
%type <str> ECPGDescribe
|
%type <str> ECPGDescribe
|
||||||
%type <str> ECPGDisconnect
|
%type <str> ECPGDisconnect
|
||||||
%type <str> ECPGExecuteImmediateStmt
|
%type <str> ECPGExecuteImmediateStmt
|
||||||
|
@ -47,6 +47,7 @@ extern struct _include_path *include_paths;
|
|||||||
extern struct cursor *cur;
|
extern struct cursor *cur;
|
||||||
extern struct typedefs *types;
|
extern struct typedefs *types;
|
||||||
extern struct _defines *defines;
|
extern struct _defines *defines;
|
||||||
|
extern struct declared_list *g_declared_list;
|
||||||
extern struct ECPGtype ecpg_no_indicator;
|
extern struct ECPGtype ecpg_no_indicator;
|
||||||
extern struct variable no_indicator;
|
extern struct variable no_indicator;
|
||||||
extern struct arguments *argsinsert;
|
extern struct arguments *argsinsert;
|
||||||
|
@ -141,6 +141,13 @@ struct cursor
|
|||||||
struct cursor *next;
|
struct cursor *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct declared_list
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char *connection;
|
||||||
|
struct declared_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct typedefs
|
struct typedefs
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -53,6 +53,7 @@ test: sql/show
|
|||||||
test: sql/insupd
|
test: sql/insupd
|
||||||
test: sql/parser
|
test: sql/parser
|
||||||
test: sql/prepareas
|
test: sql/prepareas
|
||||||
|
test: sql/declare
|
||||||
test: thread/thread
|
test: thread/thread
|
||||||
test: thread/thread_implicit
|
test: thread/thread_implicit
|
||||||
test: thread/prep
|
test: thread/prep
|
||||||
|
580
src/interfaces/ecpg/test/expected/sql-declare.c
Normal file
580
src/interfaces/ecpg/test/expected/sql-declare.c
Normal file
@ -0,0 +1,580 @@
|
|||||||
|
/* Processed by ecpg (regression mode) */
|
||||||
|
/* These include files are added by the preprocessor */
|
||||||
|
#include <ecpglib.h>
|
||||||
|
#include <ecpgerrno.h>
|
||||||
|
#include <sqlca.h>
|
||||||
|
/* End of automatic include section */
|
||||||
|
#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
|
||||||
|
|
||||||
|
#line 1 "declare.pgc"
|
||||||
|
#include <locale.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* exec sql whenever sqlerror sqlprint ; */
|
||||||
|
#line 5 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#line 1 "sqlca.h"
|
||||||
|
#ifndef POSTGRES_SQLCA_H
|
||||||
|
#define POSTGRES_SQLCA_H
|
||||||
|
|
||||||
|
#ifndef PGDLLIMPORT
|
||||||
|
#if defined(WIN32) || defined(__CYGWIN__)
|
||||||
|
#define PGDLLIMPORT __declspec (dllimport)
|
||||||
|
#else
|
||||||
|
#define PGDLLIMPORT
|
||||||
|
#endif /* __CYGWIN__ */
|
||||||
|
#endif /* PGDLLIMPORT */
|
||||||
|
|
||||||
|
#define SQLERRMC_LEN 150
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct sqlca_t
|
||||||
|
{
|
||||||
|
char sqlcaid[8];
|
||||||
|
long sqlabc;
|
||||||
|
long sqlcode;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int sqlerrml;
|
||||||
|
char sqlerrmc[SQLERRMC_LEN];
|
||||||
|
} sqlerrm;
|
||||||
|
char sqlerrp[8];
|
||||||
|
long sqlerrd[6];
|
||||||
|
/* Element 0: empty */
|
||||||
|
/* 1: OID of processed tuple if applicable */
|
||||||
|
/* 2: number of rows processed */
|
||||||
|
/* after an INSERT, UPDATE or */
|
||||||
|
/* DELETE statement */
|
||||||
|
/* 3: empty */
|
||||||
|
/* 4: empty */
|
||||||
|
/* 5: empty */
|
||||||
|
char sqlwarn[8];
|
||||||
|
/* Element 0: set to 'W' if at least one other is 'W' */
|
||||||
|
/* 1: if 'W' at least one character string */
|
||||||
|
/* value was truncated when it was */
|
||||||
|
/* stored into a host variable. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2: if 'W' a (hopefully) non-fatal notice occurred
|
||||||
|
*/ /* 3: empty */
|
||||||
|
/* 4: empty */
|
||||||
|
/* 5: empty */
|
||||||
|
/* 6: empty */
|
||||||
|
/* 7: empty */
|
||||||
|
|
||||||
|
char sqlstate[5];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sqlca_t *ECPGget_sqlca(void);
|
||||||
|
|
||||||
|
#ifndef POSTGRES_ECPG_INTERNAL
|
||||||
|
#define sqlca (*ECPGget_sqlca())
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#line 7 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
#line 1 "regression.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#line 8 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
#define ARRAY_SZIE 20
|
||||||
|
|
||||||
|
void execute_test(void);
|
||||||
|
void commitTable(void);
|
||||||
|
void reset(void);
|
||||||
|
void printResult(char *tc_name, int loop);
|
||||||
|
|
||||||
|
/* exec sql begin declare section */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#line 18 "declare.pgc"
|
||||||
|
int f1 [ ARRAY_SZIE ] ;
|
||||||
|
|
||||||
|
#line 19 "declare.pgc"
|
||||||
|
int f2 [ ARRAY_SZIE ] ;
|
||||||
|
|
||||||
|
#line 20 "declare.pgc"
|
||||||
|
char f3 [ ARRAY_SZIE ] [ 20 ] ;
|
||||||
|
/* exec sql end declare section */
|
||||||
|
#line 21 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
setlocale(LC_ALL, "C");
|
||||||
|
|
||||||
|
ECPGdebug(1, stderr);
|
||||||
|
|
||||||
|
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , "con1", 0);
|
||||||
|
#line 29 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 29 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGconnect(__LINE__, 0, "ecpg2_regression" , NULL, NULL , "con2", 0);
|
||||||
|
#line 30 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 30 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "create table source ( f1 integer , f2 integer , f3 varchar ( 20 ) )", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 32 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 32 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "create table source ( f1 integer , f2 integer , f3 varchar ( 20 ) )", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 33 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 33 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "insert into source values ( 1 , 10 , 'db on con1' )", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 35 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 35 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "insert into source values ( 2 , 20 , 'db on con1' )", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 36 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 36 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "insert into source values ( 1 , 10 , 'db on con2' )", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 38 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 38 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "insert into source values ( 2 , 20 , 'db on con2' )", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 39 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 39 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
commitTable();
|
||||||
|
|
||||||
|
execute_test();
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "drop table if exists source", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 45 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 45 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "drop table if exists source", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 46 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 46 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
commitTable();
|
||||||
|
|
||||||
|
{ ECPGdisconnect(__LINE__, "ALL");
|
||||||
|
#line 50 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 50 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* default connection: con2
|
||||||
|
* Non-default connection: con1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void execute_test(void)
|
||||||
|
{
|
||||||
|
/* exec sql begin declare section */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#line 63 "declare.pgc"
|
||||||
|
int i ;
|
||||||
|
|
||||||
|
#line 64 "declare.pgc"
|
||||||
|
char * selectString = "SELECT f1,f2,f3 FROM source" ;
|
||||||
|
/* exec sql end declare section */
|
||||||
|
#line 65 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* testcase1. using DECLARE STATEMENT without using AT clause,
|
||||||
|
* using PREPARE and CURSOR statement without using AT clause
|
||||||
|
*/
|
||||||
|
reset();
|
||||||
|
|
||||||
|
/* declare \"stmt_1\" as an SQL identifier */
|
||||||
|
#line 73 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGprepare(__LINE__, NULL, 0, "stmt_1", selectString);
|
||||||
|
#line 74 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 74 "declare.pgc"
|
||||||
|
|
||||||
|
/* declare cur_1 cursor for $1 */
|
||||||
|
#line 75 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_1 cursor for $1",
|
||||||
|
ECPGt_char_variable,(ECPGprepared_statement(NULL, "stmt_1", __LINE__)),(long)1,(long)1,(1)*sizeof(char),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 76 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 76 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
/* exec sql whenever not found break ; */
|
||||||
|
#line 78 "declare.pgc"
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_1", ECPGt_EOIT,
|
||||||
|
ECPGt_int,&(f1[i]),(long)1,(long)1,sizeof(int),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
|
ECPGt_int,&(f2[i]),(long)1,(long)1,sizeof(int),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
|
ECPGt_char,(f3[i]),(long)20,(long)1,(20)*sizeof(char),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
|
||||||
|
#line 82 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
|
||||||
|
#line 82 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 82 "declare.pgc"
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_1", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 85 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 85 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdeallocate(__LINE__, 0, NULL, "stmt_1");
|
||||||
|
#line 86 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 86 "declare.pgc"
|
||||||
|
|
||||||
|
/* exec sql whenever not found continue ; */
|
||||||
|
#line 87 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
printResult("testcase1", 2);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* testcase2. using DECLARE STATEMENT at con1,
|
||||||
|
* using PREPARE and CURSOR statement without using AT clause
|
||||||
|
*/
|
||||||
|
reset();
|
||||||
|
|
||||||
|
/* declare \"stmt_2\" as an SQL identifier */
|
||||||
|
#line 98 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGprepare(__LINE__, "con1", 0, "stmt_2", selectString);
|
||||||
|
#line 99 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 99 "declare.pgc"
|
||||||
|
|
||||||
|
/* declare cur_2 cursor for $1 */
|
||||||
|
#line 100 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "declare cur_2 cursor for $1",
|
||||||
|
ECPGt_char_variable,(ECPGprepared_statement("con1", "stmt_2", __LINE__)),(long)1,(long)1,(1)*sizeof(char),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 101 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 101 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
/* exec sql whenever not found break ; */
|
||||||
|
#line 103 "declare.pgc"
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "fetch cur_2", ECPGt_EOIT,
|
||||||
|
ECPGt_int,&(f1[i]),(long)1,(long)1,sizeof(int),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
|
ECPGt_int,&(f2[i]),(long)1,(long)1,sizeof(int),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
|
ECPGt_char,(f3[i]),(long)20,(long)1,(20)*sizeof(char),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
|
||||||
|
#line 107 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
|
||||||
|
#line 107 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 107 "declare.pgc"
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "close cur_2", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 110 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 110 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdeallocate(__LINE__, 0, NULL, "stmt_2");
|
||||||
|
#line 111 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 111 "declare.pgc"
|
||||||
|
|
||||||
|
/* exec sql whenever not found continue ; */
|
||||||
|
#line 112 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
printResult("testcase2", 2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* testcase3. using DECLARE STATEMENT at con1,
|
||||||
|
* using PREPARE and CURSOR statement at con2
|
||||||
|
*/
|
||||||
|
reset();
|
||||||
|
|
||||||
|
/* declare \"stmt_3\" as an SQL identifier */
|
||||||
|
#line 122 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGprepare(__LINE__, "con1", 0, "stmt_3", selectString);
|
||||||
|
#line 123 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 123 "declare.pgc"
|
||||||
|
|
||||||
|
/* declare cur_3 cursor for $1 */
|
||||||
|
#line 124 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "declare cur_3 cursor for $1",
|
||||||
|
ECPGt_char_variable,(ECPGprepared_statement("con1", "stmt_3", __LINE__)),(long)1,(long)1,(1)*sizeof(char),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 125 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 125 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
/* exec sql whenever not found break ; */
|
||||||
|
#line 127 "declare.pgc"
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "fetch cur_3", ECPGt_EOIT,
|
||||||
|
ECPGt_int,&(f1[i]),(long)1,(long)1,sizeof(int),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
|
ECPGt_int,&(f2[i]),(long)1,(long)1,sizeof(int),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
|
ECPGt_char,(f3[i]),(long)20,(long)1,(20)*sizeof(char),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
|
||||||
|
#line 131 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
|
||||||
|
#line 131 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 131 "declare.pgc"
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "close cur_3", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 134 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 134 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdeallocate(__LINE__, 0, "con2", "stmt_3");
|
||||||
|
#line 135 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 135 "declare.pgc"
|
||||||
|
|
||||||
|
/* exec sql whenever not found continue ; */
|
||||||
|
#line 136 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
printResult("testcase3", 2);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* testcase4. using DECLARE STATEMENT without using AT clause,
|
||||||
|
* using PREPARE and CURSOR statement at con2
|
||||||
|
*/
|
||||||
|
reset();
|
||||||
|
|
||||||
|
/* declare \"stmt_4\" as an SQL identifier */
|
||||||
|
#line 147 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGprepare(__LINE__, "con2", 0, "stmt_4", selectString);
|
||||||
|
#line 148 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 148 "declare.pgc"
|
||||||
|
|
||||||
|
/* declare cur_4 cursor for $1 */
|
||||||
|
#line 149 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "declare cur_4 cursor for $1",
|
||||||
|
ECPGt_char_variable,(ECPGprepared_statement("con2", "stmt_4", __LINE__)),(long)1,(long)1,(1)*sizeof(char),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 150 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 150 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
/* exec sql whenever not found break ; */
|
||||||
|
#line 152 "declare.pgc"
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "fetch cur_4", ECPGt_EOIT,
|
||||||
|
ECPGt_int,&(f1[i]),(long)1,(long)1,sizeof(int),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
|
ECPGt_int,&(f2[i]),(long)1,(long)1,sizeof(int),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
|
ECPGt_char,(f3[i]),(long)20,(long)1,(20)*sizeof(char),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
|
||||||
|
#line 156 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
|
||||||
|
#line 156 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 156 "declare.pgc"
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "close cur_4", ECPGt_EOIT, ECPGt_EORT);
|
||||||
|
#line 159 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 159 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdeallocate(__LINE__, 0, "con2", "stmt_4");
|
||||||
|
#line 160 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 160 "declare.pgc"
|
||||||
|
|
||||||
|
/* exec sql whenever not found continue ; */
|
||||||
|
#line 161 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
printResult("testcase4", 2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* testcase5. using DECLARE STATEMENT without using AT clause,
|
||||||
|
* using PREPARE and EXECUTE statement without using AT clause
|
||||||
|
*/
|
||||||
|
reset();
|
||||||
|
|
||||||
|
/* declare \"stmt_5\" as an SQL identifier */
|
||||||
|
#line 171 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGprepare(__LINE__, NULL, 0, "stmt_5", selectString);
|
||||||
|
#line 172 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 172 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt_5", ECPGt_EOIT,
|
||||||
|
ECPGt_int,(f1),(long)1,(long)ARRAY_SZIE,sizeof(int),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
|
ECPGt_int,(f2),(long)1,(long)ARRAY_SZIE,sizeof(int),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
|
ECPGt_char,(f3),(long)20,(long)ARRAY_SZIE,(20)*sizeof(char),
|
||||||
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
|
||||||
|
#line 173 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 173 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
{ ECPGdeallocate(__LINE__, 0, NULL, "stmt_5");
|
||||||
|
#line 175 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 175 "declare.pgc"
|
||||||
|
|
||||||
|
|
||||||
|
printResult("testcase5", 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void commitTable()
|
||||||
|
{
|
||||||
|
{ ECPGtrans(__LINE__, "con1", "commit");
|
||||||
|
#line 182 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 182 "declare.pgc"
|
||||||
|
|
||||||
|
{ ECPGtrans(__LINE__, "con2", "commit");
|
||||||
|
#line 183 "declare.pgc"
|
||||||
|
|
||||||
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
|
#line 183 "declare.pgc"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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");
|
||||||
|
}
|
286
src/interfaces/ecpg/test/expected/sql-declare.stderr
Normal file
286
src/interfaces/ecpg/test/expected/sql-declare.stderr
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
[NO_PID]: ECPGdebug: set to 1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ECPGconnect: opening database ecpg1_regression on <DEFAULT> port <DEFAULT>
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ECPGconnect: opening database ecpg2_regression on <DEFAULT> port <DEFAULT>
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 32: query: create table source ( f1 integer , f2 integer , f3 varchar ( 20 ) ); with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 32: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 32: OK: CREATE TABLE
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 33: query: create table source ( f1 integer , f2 integer , f3 varchar ( 20 ) ); with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 33: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 33: OK: CREATE TABLE
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 35: query: insert into source values ( 1 , 10 , 'db on con1' ); with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 35: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 35: OK: INSERT 0 1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 36: query: insert into source values ( 2 , 20 , 'db on con1' ); with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 36: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 36: OK: INSERT 0 1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 38: query: insert into source values ( 1 , 10 , 'db on con2' ); with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 38: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 38: OK: INSERT 0 1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 39: query: insert into source values ( 2 , 20 , 'db on con2' ); with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 39: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 39: OK: INSERT 0 1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ECPGtrans on line 182: action "commit"; connection "con1"
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ECPGtrans on line 183: action "commit"; connection "con2"
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: prepare_common on line 74: name stmt_1; query: "SELECT f1,f2,f3 FROM source"
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 76: query: declare cur_1 cursor for SELECT f1,f2,f3 FROM source; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 76: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 76: OK: DECLARE CURSOR
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 82: query: fetch cur_1; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 82: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 82: correctly got 1 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 82: RESULT: 1 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 82: RESULT: 10 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 82: RESULT: db on con2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 82: query: fetch cur_1; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 82: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 82: correctly got 1 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 82: RESULT: 2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 82: RESULT: 20 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 82: RESULT: db on con2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 82: query: fetch cur_1; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 82: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 82: correctly got 0 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: raising sqlcode 100 on line 82: no data found on line 82
|
||||||
|
[NO_PID]: sqlca: code: 100, state: 02000
|
||||||
|
[NO_PID]: ecpg_execute on line 85: query: close cur_1; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 85: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 85: OK: CLOSE CURSOR
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: deallocate_one on line 86: name stmt_1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: prepare_common on line 99: name stmt_2; query: "SELECT f1,f2,f3 FROM source"
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 101: query: declare cur_2 cursor for SELECT f1,f2,f3 FROM source; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 101: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 101: OK: DECLARE CURSOR
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 107: query: fetch cur_2; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 107: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 107: correctly got 1 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 107: RESULT: 1 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 107: RESULT: 10 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 107: RESULT: db on con1 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 107: query: fetch cur_2; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 107: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 107: correctly got 1 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 107: RESULT: 2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 107: RESULT: 20 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 107: RESULT: db on con1 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 107: query: fetch cur_2; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 107: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 107: correctly got 0 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: raising sqlcode 100 on line 107: no data found on line 107
|
||||||
|
[NO_PID]: sqlca: code: 100, state: 02000
|
||||||
|
[NO_PID]: ecpg_execute on line 110: query: close cur_2; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 110: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 110: OK: CLOSE CURSOR
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: raising sqlcode -230 on line 111: invalid statement name "stmt_2" on line 111
|
||||||
|
[NO_PID]: sqlca: code: -230, state: 26000
|
||||||
|
SQL error: invalid statement name "stmt_2" on line 111
|
||||||
|
[NO_PID]: prepare_common on line 123: name stmt_3; query: "SELECT f1,f2,f3 FROM source"
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 125: query: declare cur_3 cursor for SELECT f1,f2,f3 FROM source; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 125: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 125: OK: DECLARE CURSOR
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 131: query: fetch cur_3; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 131: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 131: correctly got 1 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 131: RESULT: 1 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 131: RESULT: 10 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 131: RESULT: db on con1 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 131: query: fetch cur_3; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 131: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 131: correctly got 1 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 131: RESULT: 2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 131: RESULT: 20 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 131: RESULT: db on con1 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 131: query: fetch cur_3; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 131: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 131: correctly got 0 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: raising sqlcode 100 on line 131: no data found on line 131
|
||||||
|
[NO_PID]: sqlca: code: 100, state: 02000
|
||||||
|
[NO_PID]: ecpg_execute on line 134: query: close cur_3; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 134: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 134: OK: CLOSE CURSOR
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: raising sqlcode -230 on line 135: invalid statement name "stmt_3" on line 135
|
||||||
|
[NO_PID]: sqlca: code: -230, state: 26000
|
||||||
|
SQL error: invalid statement name "stmt_3" on line 135
|
||||||
|
[NO_PID]: prepare_common on line 148: name stmt_4; query: "SELECT f1,f2,f3 FROM source"
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 150: query: declare cur_4 cursor for SELECT f1,f2,f3 FROM source; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 150: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 150: OK: DECLARE CURSOR
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 156: query: fetch cur_4; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 156: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 156: correctly got 1 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 156: RESULT: 1 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 156: RESULT: 10 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 156: RESULT: db on con2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 156: query: fetch cur_4; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 156: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 156: correctly got 1 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 156: RESULT: 2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 156: RESULT: 20 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 156: RESULT: db on con2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 156: query: fetch cur_4; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 156: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 156: correctly got 0 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: raising sqlcode 100 on line 156: no data found on line 156
|
||||||
|
[NO_PID]: sqlca: code: 100, state: 02000
|
||||||
|
[NO_PID]: ecpg_execute on line 159: query: close cur_4; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 159: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 159: OK: CLOSE CURSOR
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: deallocate_one on line 160: name stmt_4
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: prepare_common on line 172: name stmt_5; query: "SELECT f1,f2,f3 FROM source"
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 173: query: SELECT f1,f2,f3 FROM source; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 173: using PQexecPrepared for "SELECT f1,f2,f3 FROM source"
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 173: correctly got 2 tuples with 3 fields
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 173: RESULT: 1 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 173: RESULT: 2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 173: RESULT: 10 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 173: RESULT: 20 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 173: RESULT: db on con2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_get_data on line 173: RESULT: db on con2 offset: -1; array: no
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: deallocate_one on line 175: name stmt_5
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 45: query: drop table if exists source; with 0 parameter(s) on connection con1
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 45: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 45: OK: DROP TABLE
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 46: query: drop table if exists source; with 0 parameter(s) on connection con2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_execute on line 46: using PQexec
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_process_output on line 46: OK: DROP TABLE
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ECPGtrans on line 182: action "commit"; connection "con1"
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ECPGtrans on line 183: action "commit"; connection "con2"
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_finish: connection con2 closed
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: deallocate_one on line 0: name stmt_3
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: deallocate_one on line 0: name stmt_2
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
[NO_PID]: ecpg_finish: connection con1 closed
|
||||||
|
[NO_PID]: sqlca: code: 0, state: 00000
|
20
src/interfaces/ecpg/test/expected/sql-declare.stdout
Normal file
20
src/interfaces/ecpg/test/expected/sql-declare.stdout
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
****testcase1 test results:****
|
||||||
|
f1=1, f2=10, f3=db on con2
|
||||||
|
f1=2, f2=20, f3=db on con2
|
||||||
|
|
||||||
|
****testcase2 test results:****
|
||||||
|
f1=1, f2=10, f3=db on con1
|
||||||
|
f1=2, f2=20, f3=db on con1
|
||||||
|
|
||||||
|
****testcase3 test results:****
|
||||||
|
f1=1, f2=10, f3=db on con1
|
||||||
|
f1=2, f2=20, f3=db on con1
|
||||||
|
|
||||||
|
****testcase4 test results:****
|
||||||
|
f1=1, f2=10, f3=db on con2
|
||||||
|
f1=2, f2=20, f3=db on con2
|
||||||
|
|
||||||
|
****testcase5 test results:****
|
||||||
|
f1=1, f2=10, f3=db on con2
|
||||||
|
f1=2, f2=20, f3=db on con2
|
||||||
|
|
2
src/interfaces/ecpg/test/sql/.gitignore
vendored
2
src/interfaces/ecpg/test/sql/.gitignore
vendored
@ -10,6 +10,8 @@
|
|||||||
/copystdout.c
|
/copystdout.c
|
||||||
/createtableas
|
/createtableas
|
||||||
/createtableas.c
|
/createtableas.c
|
||||||
|
/declare
|
||||||
|
/declare.c
|
||||||
/define
|
/define
|
||||||
/define.c
|
/define.c
|
||||||
/desc
|
/desc
|
||||||
|
@ -26,6 +26,7 @@ TESTS = array array.c \
|
|||||||
insupd insupd.c \
|
insupd insupd.c \
|
||||||
twophase twophase.c \
|
twophase twophase.c \
|
||||||
insupd insupd.c \
|
insupd insupd.c \
|
||||||
|
declare declare.c \
|
||||||
bytea bytea.c \
|
bytea bytea.c \
|
||||||
prepareas prepareas.c
|
prepareas prepareas.c
|
||||||
|
|
||||||
|
207
src/interfaces/ecpg/test/sql/declare.pgc
Normal file
207
src/interfaces/ecpg/test/sql/declare.pgc
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
#include <locale.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
EXEC SQL WHENEVER SQLERROR SQLPRINT;
|
||||||
|
|
||||||
|
EXEC SQL INCLUDE sqlca;
|
||||||
|
EXEC SQL INCLUDE ../regression;
|
||||||
|
|
||||||
|
#define ARRAY_SZIE 20
|
||||||
|
|
||||||
|
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_SZIE];
|
||||||
|
int f2[ARRAY_SZIE];
|
||||||
|
char f3[ARRAY_SZIE][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;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user