Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
b3b35e98
Commit
b3b35e98
authored
Feb 17, 2000
by
Michael Meskes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
parent
3ca3bb7d
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
855 additions
and
753 deletions
+855
-753
src/interfaces/ecpg/TODO
src/interfaces/ecpg/TODO
+3
-2
src/interfaces/ecpg/lib/README.dynSQL
src/interfaces/ecpg/lib/README.dynSQL
+20
-0
src/interfaces/ecpg/lib/dynamic.c
src/interfaces/ecpg/lib/dynamic.c
+1
-16
src/interfaces/ecpg/preproc/Makefile
src/interfaces/ecpg/preproc/Makefile
+1
-2
src/interfaces/ecpg/preproc/descriptor.c
src/interfaces/ecpg/preproc/descriptor.c
+400
-0
src/interfaces/ecpg/preproc/ecpg.c
src/interfaces/ecpg/preproc/ecpg.c
+4
-0
src/interfaces/ecpg/preproc/extern.h
src/interfaces/ecpg/preproc/extern.h
+23
-3
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/preproc.y
+37
-724
src/interfaces/ecpg/preproc/type.c
src/interfaces/ecpg/preproc/type.c
+1
-0
src/interfaces/ecpg/preproc/variable.c
src/interfaces/ecpg/preproc/variable.c
+358
-0
src/interfaces/ecpg/test/Makefile
src/interfaces/ecpg/test/Makefile
+1
-1
src/interfaces/ecpg/test/dyntest.pgc
src/interfaces/ecpg/test/dyntest.pgc
+2
-2
src/interfaces/ecpg/test/test4.pgc
src/interfaces/ecpg/test/test4.pgc
+4
-3
No files found.
src/interfaces/ecpg/TODO
View file @
b3b35e98
...
...
@@ -23,8 +23,9 @@ indicator-error?
Add a semantic check level, e.g. check if a table really exists.
It would be nice if there was a alternative library using SPI functions
instead of libpq so we can write backend functions using ecpg.
Missing statements:
- exec sql ifdef
- exec sql allocate
- exec sql deallocate
- SQLSTATE
src/interfaces/ecpg/lib/README.dynSQL
0 → 100644
View file @
b3b35e98
descriptor statements have the following shortcomings
- up to now the only reasonable statement is
FETCH ... INTO SQL DESCRIPTOR <name>
no input variables allowed!
Reason: to fully support dynamic SQL the frontend/backend communication
should change to recognize input parameters.
Since this is not likely to happen in the near future and you
can cover the same functionality with the existing infrastructure
I'll leave the work to someone else.
- string buffer overflow does not always generate warnings
(beware: terminating 0 may be missing because strncpy is used)
:var=data sets sqlwarn accordingly (but not indicator)
- char variables pointing to NULL are not allocated on demand
- string truncation does not show up in indicator
src/interfaces/ecpg/lib/dynamic.c
View file @
b3b35e98
...
...
@@ -2,26 +2,11 @@
*
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
*
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/dynamic.c,v 1.
1 2000/02/16 16:18:12
meskes Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/dynamic.c,v 1.
2 2000/02/17 19:48:41
meskes Exp $
*/
/* I borrowed the include files from ecpglib.c, maybe we don't need all of them */
#if 0
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <locale.h>
#include <libpq-fe.h>
#include <libpq/pqcomm.h>
#include <ecpgtype.h>
#include <ecpglib.h>
#include <sqlca.h>
#endif
#include <sql3types.h>
static
struct
descriptor
...
...
src/interfaces/ecpg/preproc/Makefile
View file @
b3b35e98
...
...
@@ -10,8 +10,7 @@ CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
-DINCLUDE_PATH
=
\"
$(HEADERDIR)
\"
-g
OBJ
=
preproc.o pgc.o type.o ecpg.o ecpg_keywords.o
\
keywords.o c_keywords.o ../lib/typename.o
#../../../backend/parser/scansup.o
keywords.o c_keywords.o ../lib/typename.o descriptor.o variable.o
all
::
ecpg
...
...
src/interfaces/ecpg/preproc/descriptor.c
0 → 100644
View file @
b3b35e98
This diff is collapsed.
Click to expand it.
src/interfaces/ecpg/preproc/ecpg.c
View file @
b3b35e98
...
...
@@ -241,6 +241,10 @@ main(int argc, char *const argv[])
/* and structure member lists */
memset
(
struct_member_list
,
0
,
sizeof
(
struct_member_list
));
/* finally the actual connection */
connection
=
NULL
;
/* initialize lex */
lex_init
();
...
...
src/interfaces/ecpg/preproc/extern.h
View file @
b3b35e98
...
...
@@ -18,6 +18,9 @@ extern int yylineno,
yyleng
;
extern
FILE
*
yyin
,
*
yyout
;
extern
char
*
descriptor_index
;
extern
char
*
descriptor_name
;
extern
char
*
connection
;
extern
struct
_include_path
*
include_paths
;
extern
struct
cursor
*
cur
;
...
...
@@ -42,9 +45,26 @@ extern void yyerror(char *);
extern
void
*
mm_alloc
(
size_t
),
*
mm_realloc
(
void
*
,
size_t
);
extern
char
*
mm_strdup
(
const
char
*
);
extern
void
mmerror
(
enum
errortype
,
char
*
);
ScanKeyword
*
ScanECPGKeywordLookup
(
char
*
);
ScanKeyword
*
ScanCKeywordLookup
(
char
*
);
extern
ScanKeyword
*
ScanECPGKeywordLookup
(
char
*
);
extern
ScanKeyword
*
ScanCKeywordLookup
(
char
*
);
extern
void
output_get_descr_header
(
char
*
);
extern
void
output_get_descr
(
char
*
);
extern
void
push_assignment
(
char
*
,
char
*
);
extern
struct
variable
*
find_variable
(
char
*
);
extern
void
whenever_action
(
int
);
extern
void
add_descriptor
(
char
*
,
char
*
);
extern
void
drop_descriptor
(
char
*
,
char
*
);
extern
struct
descriptor
*
lookup_descriptor
(
char
*
,
char
*
);
extern
void
output_statement_desc
(
char
*
,
int
);
extern
void
add_variable
(
struct
arguments
**
,
struct
variable
*
,
struct
variable
*
);
extern
void
dump_variables
(
struct
arguments
*
,
int
);
extern
struct
typedefs
*
get_typedef
(
char
*
);
extern
void
adjust_array
(
enum
ECPGttype
,
int
*
,
int
*
,
int
,
int
,
bool
);
extern
void
reset_variables
(
void
);
extern
void
check_indicator
(
struct
ECPGtype
*
);
extern
void
remove_variables
(
int
);
extern
struct
variable
*
new_variable
(
const
char
*
,
struct
ECPGtype
*
);
/* return codes */
#define OK 0
...
...
src/interfaces/ecpg/preproc/preproc.y
View file @
b3b35e98
This diff is collapsed.
Click to expand it.
src/interfaces/ecpg/preproc/type.c
View file @
b3b35e98
...
...
@@ -2,6 +2,7 @@
#include <string.h>
#include <stdlib.h>
#include "postgres.h"
#include "extern.h"
/* malloc + error check */
...
...
src/interfaces/ecpg/preproc/variable.c
0 → 100644
View file @
b3b35e98
#include "postgres.h"
#include "extern.h"
struct
variable
*
allvariables
=
NULL
;
struct
variable
*
new_variable
(
const
char
*
name
,
struct
ECPGtype
*
type
)
{
struct
variable
*
p
=
(
struct
variable
*
)
mm_alloc
(
sizeof
(
struct
variable
));
p
->
name
=
mm_strdup
(
name
);
p
->
type
=
type
;
p
->
brace_level
=
braces_open
;
p
->
next
=
allvariables
;
allvariables
=
p
;
return
(
p
);
}
static
struct
variable
*
find_struct_member
(
char
*
name
,
char
*
str
,
struct
ECPGstruct_member
*
members
)
{
char
*
next
=
strchr
(
++
str
,
'.'
),
c
=
'\0'
;
if
(
next
!=
NULL
)
{
c
=
*
next
;
*
next
=
'\0'
;
}
for
(;
members
;
members
=
members
->
next
)
{
if
(
strcmp
(
members
->
name
,
str
)
==
0
)
{
if
(
c
==
'\0'
)
{
/* found the end */
switch
(
members
->
typ
->
typ
)
{
case
ECPGt_array
:
return
(
new_variable
(
name
,
ECPGmake_array_type
(
members
->
typ
->
u
.
element
,
members
->
typ
->
size
)));
case
ECPGt_struct
:
case
ECPGt_union
:
return
(
new_variable
(
name
,
ECPGmake_struct_type
(
members
->
typ
->
u
.
members
,
members
->
typ
->
typ
)));
default:
return
(
new_variable
(
name
,
ECPGmake_simple_type
(
members
->
typ
->
typ
,
members
->
typ
->
size
)));
}
}
else
{
*
next
=
c
;
if
(
c
==
'-'
)
{
next
++
;
return
(
find_struct_member
(
name
,
next
,
members
->
typ
->
u
.
element
->
u
.
members
));
}
else
return
(
find_struct_member
(
name
,
next
,
members
->
typ
->
u
.
members
));
}
}
}
return
(
NULL
);
}
static
struct
variable
*
find_struct
(
char
*
name
,
char
*
next
)
{
struct
variable
*
p
;
char
c
=
*
next
;
/* first get the mother structure entry */
*
next
=
'\0'
;
p
=
find_variable
(
name
);
if
(
c
==
'-'
)
{
if
(
p
->
type
->
typ
!=
ECPGt_struct
&&
p
->
type
->
typ
!=
ECPGt_union
)
{
sprintf
(
errortext
,
"variable %s is not a pointer"
,
name
);
mmerror
(
ET_FATAL
,
errortext
);
}
if
(
p
->
type
->
u
.
element
->
typ
!=
ECPGt_struct
&&
p
->
type
->
u
.
element
->
typ
!=
ECPGt_union
)
{
sprintf
(
errortext
,
"variable %s is not a pointer to a structure or a union"
,
name
);
mmerror
(
ET_FATAL
,
errortext
);
}
/* restore the name, we will need it later on */
*
next
=
c
;
next
++
;
return
find_struct_member
(
name
,
next
,
p
->
type
->
u
.
element
->
u
.
members
);
}
else
{
if
(
p
->
type
->
typ
!=
ECPGt_struct
&&
p
->
type
->
typ
!=
ECPGt_union
)
{
sprintf
(
errortext
,
"variable %s is neither a structure nor a union"
,
name
);
mmerror
(
ET_FATAL
,
errortext
);
}
/* restore the name, we will need it later on */
*
next
=
c
;
return
find_struct_member
(
name
,
next
,
p
->
type
->
u
.
members
);
}
}
static
struct
variable
*
find_simple
(
char
*
name
)
{
struct
variable
*
p
;
for
(
p
=
allvariables
;
p
;
p
=
p
->
next
)
{
if
(
strcmp
(
p
->
name
,
name
)
==
0
)
return
p
;
}
return
(
NULL
);
}
/* Note that this function will end the program in case of an unknown */
/* variable */
struct
variable
*
find_variable
(
char
*
name
)
{
char
*
next
;
struct
variable
*
p
;
if
((
next
=
strchr
(
name
,
'.'
))
!=
NULL
)
p
=
find_struct
(
name
,
next
);
else
if
((
next
=
strstr
(
name
,
"->"
))
!=
NULL
)
p
=
find_struct
(
name
,
next
);
else
p
=
find_simple
(
name
);
if
(
p
==
NULL
)
{
sprintf
(
errortext
,
"The variable %s is not declared"
,
name
);
mmerror
(
ET_FATAL
,
errortext
);
}
return
(
p
);
}
void
remove_variables
(
int
brace_level
)
{
struct
variable
*
p
,
*
prev
;
for
(
p
=
prev
=
allvariables
;
p
;
p
=
p
?
p
->
next
:
NULL
)
{
if
(
p
->
brace_level
>=
brace_level
)
{
/* remove it */
if
(
p
==
allvariables
)
prev
=
allvariables
=
p
->
next
;
else
prev
->
next
=
p
->
next
;
ECPGfree_type
(
p
->
type
);
free
(
p
->
name
);
free
(
p
);
p
=
prev
;
}
else
prev
=
p
;
}
}
/*
* Here are the variables that need to be handled on every request.
* These are of two kinds: input and output.
* I will make two lists for them.
*/
struct
arguments
*
argsinsert
=
NULL
;
struct
arguments
*
argsresult
=
NULL
;
void
reset_variables
(
void
)
{
argsinsert
=
NULL
;
argsresult
=
NULL
;
}
/* Add a variable to a request. */
void
add_variable
(
struct
arguments
**
list
,
struct
variable
*
var
,
struct
variable
*
ind
)
{
struct
arguments
*
p
=
(
struct
arguments
*
)
mm_alloc
(
sizeof
(
struct
arguments
));
p
->
variable
=
var
;
p
->
indicator
=
ind
;
p
->
next
=
*
list
;
*
list
=
p
;
}
/* Dump out a list of all the variable on this list.
This is a recursive function that works from the end of the list and
deletes the list as we go on.
*/
void
dump_variables
(
struct
arguments
*
list
,
int
mode
)
{
if
(
list
==
NULL
)
{
return
;
}
/* The list is build up from the beginning so lets first dump the
end of the list:
*/
dump_variables
(
list
->
next
,
mode
);
/* Then the current element and its indicator */
ECPGdump_a_type
(
yyout
,
list
->
variable
->
name
,
list
->
variable
->
type
,
(
list
->
indicator
->
type
->
typ
!=
ECPGt_NO_INDICATOR
)
?
list
->
indicator
->
name
:
NULL
,
(
list
->
indicator
->
type
->
typ
!=
ECPGt_NO_INDICATOR
)
?
list
->
indicator
->
type
:
NULL
,
NULL
,
NULL
);
/* Then release the list element. */
if
(
mode
!=
0
)
free
(
list
);
}
void
check_indicator
(
struct
ECPGtype
*
var
)
{
/* make sure this is a valid indicator variable */
switch
(
var
->
typ
)
{
struct
ECPGstruct_member
*
p
;
case
ECPGt_short
:
case
ECPGt_int
:
case
ECPGt_long
:
case
ECPGt_unsigned_short
:
case
ECPGt_unsigned_int
:
case
ECPGt_unsigned_long
:
break
;
case
ECPGt_struct
:
case
ECPGt_union
:
for
(
p
=
var
->
u
.
members
;
p
;
p
=
p
->
next
)
check_indicator
(
p
->
typ
);
break
;
case
ECPGt_array
:
check_indicator
(
var
->
u
.
element
);
break
;
default:
mmerror
(
ET_ERROR
,
"indicator variable must be integer type"
);
break
;
}
}
struct
typedefs
*
get_typedef
(
char
*
name
)
{
struct
typedefs
*
this
;
for
(
this
=
types
;
this
&&
strcmp
(
this
->
name
,
name
);
this
=
this
->
next
);
if
(
!
this
)
{
sprintf
(
errortext
,
"invalid datatype '%s'"
,
name
);
mmerror
(
ET_FATAL
,
errortext
);
}
return
(
this
);
}
void
adjust_array
(
enum
ECPGttype
type_enum
,
int
*
dimension
,
int
*
length
,
int
type_dimension
,
int
type_index
,
bool
pointer
)
{
if
(
type_index
>=
0
)
{
if
(
*
length
>=
0
)
mmerror
(
ET_FATAL
,
"No multi-dimensional array support"
);
*
length
=
type_index
;
}
if
(
type_dimension
>=
0
)
{
if
(
*
dimension
>=
0
&&
*
length
>=
0
)
mmerror
(
ET_FATAL
,
"No multi-dimensional array support"
);
if
(
*
dimension
>=
0
)
*
length
=
*
dimension
;
*
dimension
=
type_dimension
;
}
if
(
*
length
>=
0
&&
*
dimension
>=
0
&&
pointer
)
mmerror
(
ET_FATAL
,
"No multi-dimensional array support"
);
switch
(
type_enum
)
{
case
ECPGt_struct
:
case
ECPGt_union
:
/* pointer has to get dimension 0 */
if
(
pointer
)
{
*
length
=
*
dimension
;
*
dimension
=
0
;
}
if
(
*
length
>=
0
)
mmerror
(
ET_FATAL
,
"No multi-dimensional array support for structures"
);
break
;
case
ECPGt_varchar
:
/* pointer has to get dimension 0 */
if
(
pointer
)
*
dimension
=
0
;
/* one index is the string length */
if
(
*
length
<
0
)
{
*
length
=
*
dimension
;
*
dimension
=
-
1
;
}
break
;
case
ECPGt_char
:
case
ECPGt_unsigned_char
:
/* pointer has to get length 0 */
if
(
pointer
)
*
length
=
0
;
/* one index is the string length */
if
(
*
length
<
0
)
{
*
length
=
(
*
dimension
<
0
)
?
1
:
*
dimension
;
*
dimension
=
-
1
;
}
break
;
default:
/* a pointer has dimension = 0 */
if
(
pointer
)
{
*
length
=
*
dimension
;
*
dimension
=
0
;
}
if
(
*
length
>=
0
)
mmerror
(
ET_FATAL
,
"No multi-dimensional array support for simple data types"
);
break
;
}
}
src/interfaces/ecpg/test/Makefile
View file @
b3b35e98
...
...
@@ -27,4 +27,4 @@ stp.so: stp.c
clean
:
-
/bin/rm test1 test2 test3 test4 test5 perftest
*
.c log stp.o stp.so
-
/bin/rm test1 test2 test3 test4 test5 perftest
*
.c log stp.o stp.so
dyntest
src/interfaces/ecpg/test/dyntest.pgc
View file @
b3b35e98
...
...
@@ -2,7 +2,7 @@
*
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
*
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Attic/dyntest.pgc,v 1.
1 2000/02/16 16:18:29
meskes Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Attic/dyntest.pgc,v 1.
2 2000/02/17 19:48:58
meskes Exp $
*/
#include <stdio.h>
...
...
@@ -37,7 +37,7 @@ int main(int argc,char **argv)
exec sql allocate descriptor MYDESC;
exec sql connect to
test
;
exec sql connect to
mm
;
exec sql prepare MYQUERY from :QUERY;
exec sql declare MYCURS cursor for MYQUERY;
...
...
src/interfaces/ecpg/test/test4.pgc
View file @
b3b35e98
...
...
@@ -43,12 +43,13 @@ EXEC SQL END DECLARE SECTION;
printf("Found f=%f\n", f);
EXEC SQL SELECT
i
INTO :
i
EXEC SQL SELECT
a
INTO :
a
FROM test
WHERE f = :f;
printf("Found i=%d\n", i);
for (i = 0; i < 10; i++)
printf("Found a[%d] = %d\n", i, a[i]);
EXEC SQL DROP TABLE test;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment