Skip to content

Commit bd7c95f

Browse files
author
Michael Meskes
committed
Add DECLARE STATEMENT support to ECPG.
DECLARE STATEMENT is a statement that lets users declare an identifier pointing at a connection. This identifier will be used in other embedded dynamic SQL statement such as PREPARE, EXECUTE, DECLARE CURSOR and so on. When connecting to a non-default connection, the AT clause can be used in a DECLARE STATEMENT once and is no longer needed in every dynamic SQL statement. This makes ECPG applications easier and more efficient. Moreover, writing code without designating connection explicitly improves portability. Authors: Ideriha-san ("Ideriha, Takeshi" <ideriha.takeshi@jp.fujitsu.com>) Kuroda-san ("Kuroda, Hayato" <kuroda.hayato@jp.fujitsu.com>) Discussion: https://postgr.es/m4E72940DA2BF16479384A86D54D0988A565669DF@G01JPEXMBKW04
1 parent 02a6a54 commit bd7c95f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2334
-173
lines changed

doc/src/sgml/ecpg.sgml

+191-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ EXEC SQL CONNECT TO :target USER :user USING :passwd;
236236
SQL statements in embedded SQL programs are by default executed on
237237
the current connection, that is, the most recently opened one. If
238238
an application needs to manage multiple connections, then there are
239-
two ways to handle this.
239+
three ways to handle this.
240240
</para>
241241

242242
<para>
@@ -310,6 +310,17 @@ current=testdb2 (should be testdb2)
310310
current=testdb1 (should be testdb1)
311311
</screen>
312312
</para>
313+
314+
<para>
315+
The third option is to declare a sql identifier linked to
316+
the connection, for example:
317+
<programlisting>
318+
EXEC SQL AT <replaceable>connection-name</replaceable> DECLARE <replaceable>statement-name</replaceable> STATEMENT;
319+
EXEC SQL PREPARE <replaceable>statement-name</replaceable> FROM :<replaceable>dyn-string</replaceable>;
320+
</programlisting>
321+
Once you link a sql identifier to a connection, you execute a dynamic SQL
322+
without AT clause.
323+
</para>
313324
</sect2>
314325

315326
<sect2 id="ecpg-disconnect">
@@ -6766,6 +6777,185 @@ EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
67666777
</refsect1>
67676778
</refentry>
67686779

6780+
<refentry id="ecpg-sql-declare-statement">
6781+
<refnamediv>
6782+
<refname>DECLARE STATEMENT</refname>
6783+
<refpurpose>declares SQL statement identifier associated with connection</refpurpose>
6784+
</refnamediv>
6785+
6786+
<refsynopsisdiv>
6787+
<synopsis>
6788+
EXEC SQL [ AT <replaceable class="parameter">connection_name</replaceable> ] DECLARE <replaceable class="parameter">statement_name</replaceable> STATEMENT
6789+
</synopsis>
6790+
</refsynopsisdiv>
6791+
6792+
<refsect1>
6793+
<title>Description</title>
6794+
6795+
<para>
6796+
<command>DECLARE STATEMENT</command> declares SQL statement identifier.
6797+
SQL statement identifier is associated with connection.
6798+
</para>
6799+
6800+
<para>
6801+
<command>DELARE CURSOR</command> with a SQL statement identifier can be written before PREPARE.
6802+
</para>
6803+
</refsect1>
6804+
6805+
<refsect1>
6806+
<title>Parameters</title>
6807+
6808+
<variablelist>
6809+
<varlistentry>
6810+
<term><replaceable class="parameter">connection_name</replaceable></term>
6811+
<listitem>
6812+
<para>
6813+
A database connection name established by the <command>CONNECT</command> command.
6814+
</para>
6815+
<para>
6816+
If AT clause is omitted, an SQL statement identifier is associated with the DEFAULT connection.
6817+
</para>
6818+
</listitem>
6819+
</varlistentry>
6820+
</variablelist>
6821+
6822+
<variablelist>
6823+
<varlistentry>
6824+
<term><replaceable class="parameter">statement_name</replaceable></term>
6825+
<listitem>
6826+
<para>
6827+
The name of a SQL statement identifier, either as an SQL identifier or a host variable.
6828+
</para>
6829+
</listitem>
6830+
</varlistentry>
6831+
</variablelist>
6832+
</refsect1>
6833+
6834+
<refsect1>
6835+
<title>Notes</title>
6836+
<para>
6837+
AT clause can be used at other dynamic SQL statements. The following table
6838+
gives the connected database when AT clause is used at DECLARE STATEMENT
6839+
and other dynamic statements.
6840+
</para>
6841+
<table tocentry="1" id="ecpg-declare-statement-table">
6842+
<title>Scenario</title>
6843+
<tgroup cols="4">
6844+
<thead>
6845+
<row>
6846+
<entry>
6847+
Using Scenario
6848+
</entry>
6849+
<entry>
6850+
Declare Statement
6851+
</entry>
6852+
<entry>
6853+
Other Dynamic Statements
6854+
</entry>
6855+
<entry>
6856+
Executed Database
6857+
</entry>
6858+
</row>
6859+
</thead>
6860+
<tbody>
6861+
<row>
6862+
<entry>
6863+
1
6864+
</entry>
6865+
<entry>
6866+
Without AT clause
6867+
</entry>
6868+
<entry>
6869+
Without AT clause
6870+
</entry>
6871+
<entry>
6872+
Default connection
6873+
</entry>
6874+
</row>
6875+
<row>
6876+
<entry>
6877+
2
6878+
</entry>
6879+
<entry>
6880+
Using AT clause connecting at con1
6881+
</entry>
6882+
<entry>
6883+
Without AT clause
6884+
</entry>
6885+
<entry>
6886+
con1
6887+
</entry>
6888+
</row>
6889+
<row>
6890+
<entry>
6891+
3
6892+
</entry>
6893+
<entry>
6894+
Using AT clause connecting at con1
6895+
</entry>
6896+
<entry>
6897+
Using AT clause connecting at con2
6898+
</entry>
6899+
<entry>
6900+
con1
6901+
</entry>
6902+
</row>
6903+
<row>
6904+
<entry>
6905+
4
6906+
</entry>
6907+
<entry>
6908+
Without AT clause
6909+
</entry>
6910+
<entry>
6911+
Using AT clause connecting at con2
6912+
</entry>
6913+
<entry>
6914+
con2
6915+
</entry>
6916+
</row>
6917+
</tbody>
6918+
</tgroup>
6919+
</table>
6920+
<para>
6921+
In scenario 4, DECLARE STATEMENT will be ignored.
6922+
</para>
6923+
</refsect1>
6924+
6925+
<refsect1>
6926+
<title>Examples</title>
6927+
6928+
<programlisting>
6929+
EXEC SQL CONNECT TO postgres AS con1;
6930+
EXEC SQL AT con1 DECLARE sql_stmt STATEMENT;
6931+
EXEC SQL DECLARE cursor_name CURSOR FOR sql_stmt;
6932+
EXEC SQL PREPARE sql_stmt FROM :dyn_string;
6933+
EXEC SQL OPEN cursor_name;
6934+
EXEC SQL FETCH cursor_name INTO :column1;
6935+
EXEC SQL CLOSE cursor_name;
6936+
</programlisting>
6937+
</refsect1>
6938+
6939+
<refsect1>
6940+
<title>Compatibility</title>
6941+
6942+
<para>
6943+
<command>DECLARE STATEMENT</command> is a PostgreSQL extension of the SQL standard,
6944+
but can be used in Oracle and DB2.
6945+
</para>
6946+
</refsect1>
6947+
6948+
<refsect1>
6949+
<title>See Also</title>
6950+
6951+
<simplelist type="inline">
6952+
<member><xref linkend="ecpg-sql-connect"/></member>
6953+
<member><xref linkend="ecpg-sql-declare"/></member>
6954+
<member><xref linkend="ecpg-sql-open"/></member>
6955+
</simplelist>
6956+
</refsect1>
6957+
</refentry>
6958+
67696959
<refentry id="ecpg-sql-describe">
67706960
<refnamediv>
67716961
<refname>DESCRIBE</refname>

src/interfaces/ecpg/ecpglib/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ include $(top_builddir)/src/Makefile.global
1515

1616
PGFILEDESC = "ECPG - embedded SQL in C"
1717
NAME= ecpg
18-
SO_MAJOR_VERSION= 6
18+
SO_MAJOR_VERSION= 7
1919
SO_MINOR_VERSION= $(MAJORVERSION)
2020

2121
override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \
2222
-I$(libpq_srcdir) -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS)
2323
override CFLAGS += $(PTHREAD_CFLAGS)
2424

2525
OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o \
26-
memory.o connect.o misc.o $(WIN32RES)
26+
memory.o connect.o misc.o cursor.o $(WIN32RES)
2727

2828
SHLIB_LINK_INTERNAL = -L../pgtypeslib -lpgtypes $(libpq_pgport_shlib)
2929
SHLIB_LINK = $(filter -lintl -lm, $(LIBS)) $(PTHREAD_LIBS)

src/interfaces/ecpg/ecpglib/connect.c

+6
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
340340
return false;
341341
}
342342

343+
memset(this, 0, sizeof(struct connection));
344+
343345
if (dbname != NULL)
344346
{
345347
/* get the detail information from dbname */
@@ -690,6 +692,7 @@ ECPGdisconnect(int lineno, const char *connection_name)
690692
struct connection *f = con;
691693

692694
con = con->next;
695+
ecpg_release_declared_statement(f->name);
693696
ecpg_finish(f);
694697
}
695698
}
@@ -705,7 +708,10 @@ ECPGdisconnect(int lineno, const char *connection_name)
705708
return false;
706709
}
707710
else
711+
{
712+
ecpg_release_declared_statement(connection_name);
708713
ecpg_finish(con);
714+
}
709715
}
710716

711717
#ifdef ENABLE_THREAD_SAFETY

0 commit comments

Comments
 (0)