このセクションでは、ecpg が内部でどのように動いているかについて説明します。 この情報は、ecpg の使用法を習得したいユーザの役に立ちます。
ecpg から出力される最初の 4 行は固定です。2行はコメントで、2行はライブラリのインターフェイスに必要なinclude行です。 プリプロセッサは入力ファイルを読み、出力に書き込みます。通常はただ出力にechoします。
EXEC SQL文になると、ecpgは間に入りこれを変更します。 コマンドは exec sql で始まり、; で終わります。その中間はすべてSQL文として扱われ、変数の代用が構文解析されます。
変数の代用はシンボルがコロン (:) で始まる場合に起こります。 そしてその名前の変数が、EXEC SQL DECLARE セクションで以前宣言された変数の中から探されます。変数が入力用か出力用であるかによって、関数からのアクセスを許可するために変数へのポインタが出力に書かれます。
SQL要求の一部であるすべての変数には、関数が他の引数を与えられます。
特別シンボルとしての型
値へのポインタもしくはポインタのポインタ
変数が char か varchar の場合はそのサイズ
配列の要素数 (配列取り出し用)
配列の次の要素のオフセット (配列取り出し用)
特別シンボルとしての指示変数の型
指示変数の値へのポインタもしくは指示変数のポインタへのポインタ
0
指示配列の要素数 (配列取り出し用)
指示配列の次の要素のオフセット (配列取り出し用)
すべての SQL コマンドが上記のように処理されるとは限らないので注意してください。 例えば、次のようなカーソルをオープンする文です。
EXEC SQL OPEN cursor;
これは出力にコピーされません。かわりに、同様にカーソルをオープンする、カーソルのDECLAREコマンドが使われます。
以下に foo.pgc ファイルのプリプロセッサの完全な出力例を示します (プリプロセッサのバージョンによって多少異なる場合があります)。
EXEC SQL BEGIN DECLARE SECTION; int index; int result; EXEC SQL END DECLARE SECTION; ... EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index;
これは次のように翻訳されます。
/* Processed by ecpg (2.6.0) */ /* These two include files are added by the preprocessor */ #include <ecpgtype.h>; #include <ecpglib.h>; /* exec sql begin declare section */ #line 1 "foo.pgc" int index; int result; /* exec sql end declare section */ ... ECPGdo(__LINE__, NULL, "SELECT res FROM mytable WHERE index = ? ", ECPGt_int,&(index),1L,1L,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(result),1L,1L,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 147 "foo.pgc"
このマニュアルでは読みやすいようにインデントしてありますが、プリプロセッサはこのようにはしません。
ライブラリの中で最も重要な関数は ECPGdo です。この関数は引数の数の変数をとります。vararg() 関数に許可される変数の数が限られていないマシンを使うことを願います。そうしないと50かそれ以上の引数を追加することになるからです。
引数は以下のとおりです。
これは元の行の行番号です。エラーメッセージでのみ使用されます。
発行される SQL 要求です。その要求は入力変数により変更されます(たとえばコンパイル時には知られていなかったが要求時に入力された変数)。変数が行くべきところには?があります。
プリプロセッサの部分で説明されるように、すべての入力変数は 10 個の引数を受けます。
入力変数がもうないことを表す enum です。
プリプロセッサの部分で説明されるように、すべての入力変数は 10 個の引数を受けます。これらの変数は関数で埋められています。
変数がもうないことを表す enum です。