diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog new file mode 100644 index 0000000000..13701891d7 --- /dev/null +++ b/src/interfaces/ecpg/ChangeLog @@ -0,0 +1,11 @@ +Wed Feb 11 10:58:13 CET 1998 + + - Added '-d' option to turn on debugging. + - Added version number to ecpg. + - Made libecpg a shared library. + - All files are now installed by 'make install'. + - Added man page. + +Thu Feb 12 14:45:07 CET 1998 + + - Changed parser to correctly handle local variables. diff --git a/src/interfaces/ecpg/doc/Makefile b/src/interfaces/ecpg/doc/Makefile new file mode 100644 index 0000000000..6c8496b18f --- /dev/null +++ b/src/interfaces/ecpg/doc/Makefile @@ -0,0 +1,39 @@ +#------------------------------------------------------------------------- +# +# Makefile +# Makefile for doc directory to install man pages +# +#------------------------------------------------------------------------- + +SRCDIR=../../.. +include $(SRCDIR)/Makefile.global + +all: ecpg.texinfo + -makeinfo ecpg.texinfo + +install: install-man install-info + +install-man: + -mkdir -p $(POSTMANDIR) + -mkdir $(POSTMANDIR)/man1 + #-mkdir $(POSTMANDIR)/man3 + #-mkdir $(POSTMANDIR)/man5 + #-mkdir $(POSTMANDIR)/manl + install -m644 *.1* $(POSTMANDIR)/man1 + #install -m644 *.3* $(POSTMANDIR)/man3 + #install -m644 *.5* $(POSTMANDIR)/man5 + #install -m644 *.l* $(POSTMANDIR)/manl + +install-info: ecpg.info + install -m 755 -d $(DESTDIR)$(POSTGRESDIR)/info + install -m 644 ecpg.info $(DESTDIR)$(POSTGRESDIR)/info; \ + #if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then\ + # install-info --infodir=$(infodir) ecpg.info; \ + #else true; \ + #fi + +clean: + rm -f ecpg.info ecpg.?? ecpg.??? missfont.log *~ core + +distclean: clean + rm -f Makefile diff --git a/src/interfaces/ecpg/doc/ecpg.info b/src/interfaces/ecpg/doc/ecpg.info new file mode 100644 index 0000000000..0f33116283 --- /dev/null +++ b/src/interfaces/ecpg/doc/ecpg.info @@ -0,0 +1,587 @@ +This is Info file ecpg.info, produced by Makeinfo version 1.67 from the +input file ecpg.texinfo. + + This file documents an embedded SQL in C package for PostgreSQL. + + Copyright 1996 Linus Tolke + + Permission is granted to copy and use in the same way as you are +allowed to copy and use the rest of the PostgreSQL. + + +File: ecpg.info, Node: Top, Next: Why embedded SQL, Prev: (dir), Up: (dir) + + Ecpg is an embedded sql preprocessor for C and library for +PostgresSQL + + It is written by Linus Tolke and Michael Meskes +. + +* Menu: + +* Why embedded SQL:: +* Simple description of the concept:: +* How to use it:: +* Limitations:: +* Porting from other DBMSs:: +* Installation:: +* Index:: +* For the developer:: + + -- The Detailed Node Listing -- + +How to use it + +* Preprocessor:: +* Library:: +* Error handling:: + +For the developer + +* To do list:: +* The preprocessor:: +* A complete example:: +* The library:: + + +File: ecpg.info, Node: Why embedded SQL, Next: Simple description of the concept, Prev: Top, Up: Top + +Why embedded SQL +**************** + + Embedded SQL has some small advantages over other ways to handle SQL +queries. It takes care of all the tidious moving of information to and +from variables in your c-program. + + There is an ANSI-standard describing how the embedded language should +work. Most embedded sql preprocessors I have seen and heard of makes +extensions so it is difficult to obtain portability even between them +anyway. I have not read the standard but I hope that my implementation +does not deviate to much and that it would be possible to port programs +with embedded sql written for other DBMS:s to PostgreSQL and thus +promoting the spirit of free software. + + +File: ecpg.info, Node: Simple description of the concept, Next: How to use it, Prev: Why embedded SQL, Up: Top + +Simple description of the concept +********************************* + + You write your program in C with some special sql things. For +declaring variables that can be used in SQL statements you need to put +them in a special declare section. You use a special syntax for the +sql queries. + + Before compiling you run the file through the embedded sql c +preprocessor and it converts the SQL statements you used to function +calls with the variables used as arguments. Both variables that are used +as input to the SQL statements and variables that will contain the +result are passed. + + Then you compile and at link time you link with a special library +that contains the functions used. These functions (actually it is +mostly one single function) fetches the information from the arguments, +performs the SQL query using the ordinary interface (pq) and puts back +the result in the arguments dedicated for output. + + Then you run your program and when the control arrives to the SQL +statement the SQL statement is performed against the database and you +can continue with the result. + + +File: ecpg.info, Node: How to use it, Next: Limitations, Prev: Simple description of the concept, Up: Top + +How to use it +************* + + This chapter describes how to use the ECPG tool. + +* Menu: + +* Preprocessor:: +* Library:: +* Error handling:: + + +File: ecpg.info, Node: Preprocessor, Next: Library, Prev: How to use it, Up: How to use it + +Preprocessor +============ + + The preprocessor is called `ecpg'. After installation it resides in +the postgres `bin' directory. + + +File: ecpg.info, Node: Library, Next: Error handling, Prev: Preprocessor, Up: How to use it + +Library +======= + + The library is called `libecpg.a' resp. `libecpg.so'. The library +used the pq library for the communication to the postgres server so you +will have to link your program with `-lecpg -lpq'. + + The library has some methods that are "hidden" but that could prove +very useful sometime. + +`ECPGdebug(int, FILE *stream)' + If this is called, with the first argument non-zero, then + debuglogging is turned on. Debuglogging is done on `stream'. Most + SQL statement logs its arguments and result. + + The most important one (`ECPGdo') that is called on all SQL + statements except `EXEC SQL COMMIT', `EXEC SQL ROLLBACK', `EXEC + SQL CONNECT' logs both its expanded string, i.e. the string with + all the input variables inserted, and the result from the + PostgreSQL server. This can be very useful when searching for + errors in your SQL statements. + +`ECPGstatus()' + This method returns TRUE if we are connected to a database and + FALSE if not. + + +File: ecpg.info, Node: Error handling, Prev: Library, Up: How to use it + +Error handling +============== + + To be able to detect errors from the postgres server you include a +line like: + exec sql include sqlca; + in the include section of your file. This will define a struct and a +variable with the name `sqlca' as following: + struct sqlca { + int sqlcode; + struct { + int sqlerrml; + char sqlerrmc[1000]; + } sqlerrm; + } sqlca; + + If an error occured in the last SQL statement then `sqlca.sqlcode' +will be non-zero. If `sqlca.sqlcode' is less that 0 then this is some +kind of serious error, like the database definition does not match the +query given. If it is bigger than 0 then this is a normal error like +the table did not contain the requested row. + + sqlca.sqlerrm.sqlerrmc will contain a string that describes the +error. The string ends with `line 23.' where the line is the line +number in the source file (actually the file generated by the +preprocessor but I hope I can fix this to be the line number in the +input file.) + + List of errors that can occur: +-1, Unsupported type %s on line %d. + Does not normally occur. This is a sign that the preprocessor has + generated something that the library does not know about. Perhaps + you are running incompatible versions of the preprocessor and the + library. + +-1, Too many arguments line %d. +-1, Too few arguments line %d. + The preprocessor has goofed up and generated some incorrect code. + +-1, Error starting transaction line %d. + PostgreSQL signalled to us that we cannot open the connection. + +-1, Postgres error: %s line %d. + Some PostgreSQL error. The message contains the error message from + the PostgreSQL backend. + +1, Data not found line %d. + This is a "normal" error that tells you that what you are quering + cannot be found or we have gone through the cursor. + +-1, To many matches line %d. + This means that the query has returned several lines. The `SELECT' + you made probably was not unique. + +-1, Not correctly formatted int type: %s line %d. + This means that the host variable is of an `int' type and the field + in the PostgreSQL database is of another type and contains a value + that cannot be interpreted as an `int'. The library uses `strtol' + for this conversion. + +-1, Not correctly formatted unsigned type: %s line %d. + This means that the host variable is of an `unsigned int' type and + the field in the PostgreSQL database is of another type and + contains a value that cannot be interpreted as an `unsigned int'. + The library uses `strtoul' for this conversion. + +-1, Not correctly formatted floating point type: %s line %d. + This means that the host variable is of an `float' type and the + field in the PostgreSQL database is of another type and contains a + value that cannot be interpreted as an `float'. The library uses + `strtod' for this conversion. + +-1, Too few arguments line %d. + This means that PostgreSQL has returned more records than we have + matching variables. Perhaps you have forgotten a couple of the host + variables in the `INTO :var1,:var2'-list. + +-1, Too many arguments line %d. + This means that PostgreSQL has returned fewer records than we have + host variables. Perhaps you have to many host variables in the + `INTO :var1,:var2'-list. + +-1, Empty query line %d. + PostgreSQL returned PGRES_EMPTY_QUERY. + +-1, Error: %s line %d. + This means that PostgreSQL returned on of the errors + PGRES_NONFATAL_ERROR, PGRES_FATAL_ERROR or PGRES_BAD_RESPONSE. + Which one and why is explained in the message. + +-1, Postgres error line %d. + PostgreSQL returns something that the library does not know how to + handle. This is probably because the version of PostgreSQL does not + match the version of the ecpg library. + +-1, Error committing line %d. + Error during `COMMIT'. `EXEC SQL COMMIT' is translated to an `end' + operation in PostgreSQL and that is the operation that could not + be performed. + +-1, Error rolling back line %d. + Error during `ROLLBACK'. `EXEC SQL ROLLBACK' is translated to an + `abort' operation in PostgreSQL and that is the operation that + could not be performed. + +-1, ECPGconnect: could not open database %s. + The connect to the database did not work. + + +File: ecpg.info, Node: Limitations, Next: Porting from other DBMSs, Prev: How to use it, Up: Top + +Limitations +*********** + + What will never be included and why or what cannot be done with this +concept. + +oracles single tasking possibility + Oracle version 7.0 on AIX 3 uses the OS-supported locks on the + shared memory segments and allows the application designer to link + an application in a so called single tasking way. Instead of + starting one client process per application process both the + database part and the application part is run in the same process. + In later versions of oracle this is no longer supported. + + This would require a total redesign of the postgres access model + and that effort can not justify the performance gained. + + +File: ecpg.info, Node: Porting from other DBMSs, Next: Installation, Prev: Limitations, Up: Top + +Porting from other DBMSs +************************ + + To be written by persons that knows the different DBMSs and that +actually does port something... + + +File: ecpg.info, Node: Installation, Next: Index, Prev: Porting from other DBMSs, Up: Top + +Installation +************ + + Since version 0.5 ecpg is distributed together with PostgreSQL. So +you should get your precompiler, libraries and header files compiled and +installed on the fly. + + +File: ecpg.info, Node: Index, Next: For the developer, Prev: Installation, Up: Top + +Index +***** + +* Menu: + +* -lecpg: Library. +* debuglogging: Library. +* ecpg: Preprocessor. +* ECPGdebug(int, FILE *stream): Library. +* ECPGstatus(): Library. +* error list: Error handling. +* error messages: Error handling. +* installation: Installation. +* libecpg.a: Library. +* library functions: Library. +* preprocessor: Preprocessor. +* single tasking: Limitations. +* sqlca.h: Error handling. +* sqlcode: Error handling. +* struct sqlca: Error handling. + + +File: ecpg.info, Node: For the developer, Prev: Index, Up: Top + +For the developer +***************** + + This chapter is for those that wants to develop the ecpg interface. +It describes how the things work. The ambition is to make this chapter +contain things for those that want to have a look inside and the chapter +on How to use it should be enough for all normal questions. + + So, read this before looking at the internals of the `ecpg'. If you +are not interested in how it really works, skip this chapter. + +* Menu: + +* To do list:: +* The preprocessor:: +* A complete example:: +* The library:: + + +File: ecpg.info, Node: To do list, Next: The preprocessor, Prev: For the developer, Up: For the developer + +To do list +========== + + In the alpha version the preprocessor has a lot of flaws: +Preprocessor output + The variables should be static. + +Preprocessor cannot do syntax checking on your SQL statements + Whatever you write is copied more or less exactly to the + PostgreSQL and you will not be able to locate your errors until + run-time. + +no restriction to strings only + The PQ interface, and most of all the PQexec function, that is + used by the ecpg relies on that the request is built up as a + string. In some cases, like when the data contains the null + character, this will be a serious problem. + +error codes + There should be different error numbers for the different errors + instead of just -1 for them all. + +library functions + to_date et al. + +records + Possibility to define records or `struct's in the declare section + in a way that the record can be filled from one row in the + database. + + This is a simpler way to handle an entire row at a time. + +array operations + Oracle has array operations that enhances speed. When implementing + it in `ecpg' it is done for compatibility reasons only. For them to + improve speed would require a lot more insight in the postgres + internal mechanisms than I possess. + +indicator variables + Oracle has indicator variables that tell if a value is `null' or if + it is empty. This largely simplifies array operations and provides + for a way to hack around some design flaws in the handling of + `VARCHAR2' (1). I am not sure if this is an Oracle extension or + part of the ANSI standard. + +typedefs + As well as complex types like records and arrays, typedefs would be + a good thing to take care of. + +conversion of scripts + To set up a database you need a few scripts with table definitions + and other configuration parameters. If you have these scripts for + an old database you would like to just apply them to get a + postgres database that works in the same way. + + The functionality could be accomplished with some conversion + scripts. Speed will never be accomplished in this way. To do this + you need a bigger insight in the database construction and the use + of the database than could be realised in a script. + + ---------- Footnotes ---------- + + (1) like that an empty string isn't distinguishable from a `null' +value + + +File: ecpg.info, Node: The preprocessor, Next: A complete example, Prev: To do list, Up: For the developer + +The preprocessor +================ + + First four lines are written to the output. Two comments and two +include lines necessary for the interface to the library. + + Then the preprocessor works in one pass only reading the input file +and writing to the output as it goes along. Normally it just echoes +everything to the output without looking at it further. + + When it comes to an `EXEC SQL' statements it interviens and changes +them depending on what iit is. The `EXEC SQL' statement can be one of +these: + + * Declare sections Declare sections begins with + exec sql begin declare section; + and ends with + exec sql end declare section; + In the section only variable declarations are allowed. Every + variable declare within this section is also entered in a list of + variables indexed on their name together with the corresponding + type. + + The declaration is echoed to the file to make the variable a normal + C-variable also. + + The special types VARCHAR and VARCHAR2 are converted into a named + struct for every variable. A declaration like: + VARCHAR var[180]; + is converted into + struct varchar_var { int len; char arr[180]; } var; + + * Include statements An include statement looks like: + exec sql include filename; + It is converted into + #include + + * Connect statement A connect statements looks like: + exec sql connect 'databasename'; + That statement is converted into + ECPGconnect("databasename"); + + * Open cursor statement An open cursor statement looks like: + exec sql open blablabla; + and is ignore and not copied from the output. + + * Commit statement A commit statement looks like + exec sql commit; + and is translated on the output to + ECPGcommit(__LINE__); + + * Rollback statement A rollback statement looks like + exec sql rollback; + and is translated on the output to + ECPGrollback(__LINE__); + + * Other statements Other SQL statements are other statements that + start with `exec sql' and ends with `;'. Everything inbetween is + treated as an sql statement and parsed for variable substitution. + + Variable substitution occur when a symbol starts with a colon + (`:'). Then a variable with that name is found among the variables + that were previously declared within a declare section and + depending on whether or not the SQL statements knows it to be a + variable for input or output the pointers to the variables are + written to the output to allow for access by the function. + + For every variable that is part of the SQL request the function + gets another five arguments. + 1. The type as a special symbol + + 2. A pointer to the value + + 3. The size of the variable if it is a varchar + + 4. Number of elements in the array (for array fetches) + + 5. The offset to the next element in the array (for array + fetches) + Since the array fetches are not implemented yet the two last + arguments are not really important. They could perhaps have been + left out. + + +File: ecpg.info, Node: A complete example, Next: The library, Prev: The preprocessor, Up: For the developer + +A complete example +================== + + Here is a complete example describing the output of the preprocessor: + 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; + is translated into: + /* These two include files are added by the preprocessor */ + #include + #include + /* exec sql begin declare section */ + + int index; + int result; + /* exec sql end declare section */ + + ... + ECPGdo(__LINE__, "select res from mytable where index = ;;", + ECPGt_int,&index,0,0,sizeof(int), + ECPGt_EOIT, + ECPGt_int,&result,0,0,sizeof(int), + ECPGt_EORT ); + (the indentation in this manual is added for readability and not +something that the preprocessor can do.) + + +File: ecpg.info, Node: The library, Prev: A complete example, Up: For the developer + +The library +=========== + + The most important function in the library is the `ECPGdo' function. +It takes a variable amount of arguments. Hopefully we wont run into +machines with limits on the amount of variables that can be accepted by +a varchar function. This could easily add up to 50 or so arguments. + + The arguments are: +A line number + This is a line number for the original line used in error messages + only. + +A string + This is the sql request that is to be issued. This request is + modified by the input variables, i.e. the variables that where not + known at compile time but are to be entered in the request. Where + the variables should go the string contains `;;'. + +Input variables + As described in the section about the preprocessor every input + variable gets five arguments. + +ECPGt_EOIT + An enum telling that there are no more input variables. + +Output variables + As described in the section about the preprocessor every input + variable gets five arguments. These variables are filled by the + function. + +ECPGt_EORT + An enum telling that there are no more variables. + + All the SQL statements are performed in one transaction unless you +issue a commit transaction. This works so that the first transaction or +the first after a commit or rollback always begins a transaction. + + To be completed: entries describing the other entries. + + + +Tag Table: +Node: Top319 +Node: Why embedded SQL940 +Node: Simple description of the concept1722 +Node: How to use it2921 +Node: Preprocessor3174 +Node: Library3401 +Node: Error handling4495 +Node: Limitations8883 +Node: Porting from other DBMSs9668 +Node: Installation9923 +Node: Index10213 +Node: For the developer11130 +Node: To do list11731 +Node: The preprocessor14242 +Node: A complete example17511 +Node: The library18547 + +End Tag Table diff --git a/src/interfaces/ecpg/test/mm.sql b/src/interfaces/ecpg/test/mm.sql new file mode 100644 index 0000000000..923825fabb --- /dev/null +++ b/src/interfaces/ecpg/test/mm.sql @@ -0,0 +1,8 @@ +create table meskes(name char8, born int4); + +insert into meskes(name, born) values ('Petra', 19661202); +insert into meskes(name, born) values ('Michael', 19660117); +insert into meskes(name, born) values ('Carsten', 19910103); +insert into meskes(name, born) values ('Marc', 19930907); +insert into meskes(name, born) values ('Chris', 19970923); +