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
c6dd1e63
Commit
c6dd1e63
authored
Aug 11, 1998
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
This one cleans the cursor problems ecpg had so far. It is now able
to understand cursors with variables. Michael
parent
79c8d2e3
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
333 additions
and
231 deletions
+333
-231
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/ChangeLog
+7
-0
src/interfaces/ecpg/TODO
src/interfaces/ecpg/TODO
+1
-3
src/interfaces/ecpg/include/ecpglib.h
src/interfaces/ecpg/include/ecpglib.h
+0
-3
src/interfaces/ecpg/lib/Makefile.in
src/interfaces/ecpg/lib/Makefile.in
+1
-1
src/interfaces/ecpg/lib/ecpglib.c
src/interfaces/ecpg/lib/ecpglib.c
+225
-201
src/interfaces/ecpg/preproc/ecpg.c
src/interfaces/ecpg/preproc/ecpg.c
+19
-0
src/interfaces/ecpg/preproc/extern.h
src/interfaces/ecpg/preproc/extern.h
+18
-0
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/preproc.y
+56
-17
src/interfaces/ecpg/test/Makefile
src/interfaces/ecpg/test/Makefile
+1
-1
src/interfaces/ecpg/test/test2.pgc
src/interfaces/ecpg/test/test2.pgc
+5
-5
No files found.
src/interfaces/ecpg/ChangeLog
View file @
c6dd1e63
...
@@ -270,3 +270,10 @@ Mon Aug 3 17:23:18 CEST 1998
...
@@ -270,3 +270,10 @@ Mon Aug 3 17:23:18 CEST 1998
- Fixed cursor handling
- Fixed cursor handling
- Set version to 2.3.5
- Set version to 2.3.5
- Set library version to 2.4
- Set library version to 2.4
Fri Aug 7 12:38:50 CEST 1998
- Fixed cursor handling once again
- Added support for variables in cursor
- Set version to 2.3.6
- Set library version to 2.5
src/interfaces/ecpg/TODO
View file @
c6dd1e63
What happens to a cursor declaration with variables?
The complete structure definition has to be listed inside the declare
The complete structure definition has to be listed inside the declare
section of the structure variable for ecpg to be able to understand it.
section of the structure variable for ecpg to be able to understand it.
Variable type bool has to be
check
ed. I never used it so far.
Variable type bool has to be
test
ed. I never used it so far.
The error message for "no data" in an exec sql insert select from statement
The error message for "no data" in an exec sql insert select from statement
has to be 100.
has to be 100.
...
...
src/interfaces/ecpg/include/ecpglib.h
View file @
c6dd1e63
...
@@ -13,9 +13,6 @@ bool ECPGdisconnect(int, const char *);
...
@@ -13,9 +13,6 @@ bool ECPGdisconnect(int, const char *);
void
ECPGlog
(
const
char
*
format
,...);
void
ECPGlog
(
const
char
*
format
,...);
bool
ECPGdeclare
(
int
,
const
char
*
,
char
*
);
bool
ECPGopen
(
int
,
const
char
*
);
#ifdef LIBPQ_FE_H
#ifdef LIBPQ_FE_H
bool
ECPGsetdb
(
PGconn
*
);
bool
ECPGsetdb
(
PGconn
*
);
...
...
src/interfaces/ecpg/lib/Makefile.in
View file @
c6dd1e63
...
@@ -4,7 +4,7 @@ include $(SRCDIR)/Makefile.global
...
@@ -4,7 +4,7 @@ include $(SRCDIR)/Makefile.global
PQ_INCLUDE
=
-I
$(SRCDIR)
/interfaces/libpq
PQ_INCLUDE
=
-I
$(SRCDIR)
/interfaces/libpq
SO_MAJOR_VERSION
=
2
SO_MAJOR_VERSION
=
2
SO_MINOR_VERSION
=
4
SO_MINOR_VERSION
=
5
PORTNAME
=
@PORTNAME@
PORTNAME
=
@PORTNAME@
...
...
src/interfaces/ecpg/lib/ecpglib.c
View file @
c6dd1e63
...
@@ -33,6 +33,29 @@ static struct connection
...
@@ -33,6 +33,29 @@ static struct connection
struct
connection
*
next
;
struct
connection
*
next
;
}
*
all_connections
=
NULL
,
*
actual_connection
=
NULL
;
}
*
all_connections
=
NULL
,
*
actual_connection
=
NULL
;
struct
variable
{
enum
ECPGttype
type
;
void
*
value
;
long
varcharsize
;
long
arrsize
;
long
offset
;
enum
ECPGttype
ind_type
;
void
*
ind_value
;
long
ind_varcharsize
;
long
ind_arrsize
;
long
ind_offset
;
struct
variable
*
next
;
};
struct
statement
{
int
lineno
;
char
*
command
;
struct
variable
*
inlist
;
struct
variable
*
outlist
;
};
static
int
simple_debug
=
0
;
static
int
simple_debug
=
0
;
static
FILE
*
debugstream
=
NULL
;
static
FILE
*
debugstream
=
NULL
;
static
int
committed
=
true
;
static
int
committed
=
true
;
...
@@ -116,27 +139,87 @@ ECPGfinish(struct connection *act)
...
@@ -116,27 +139,87 @@ ECPGfinish(struct connection *act)
ECPGlog
(
"ECPGfinish: called an extra time.
\n
"
);
ECPGlog
(
"ECPGfinish: called an extra time.
\n
"
);
}
}
bool
/* create a list of variables */
ECPGdo
(
int
lineno
,
char
*
query
,...)
static
bool
create_statement
(
int
lineno
,
struct
statement
**
stmt
,
char
*
query
,
va_list
ap
)
{
struct
variable
**
list
=
&
((
*
stmt
)
->
inlist
);
enum
ECPGttype
type
;
*
stmt
=
calloc
(
sizeof
(
struct
statement
),
1
);
if
(
!*
stmt
)
{
ECPGfinish
(
actual_connection
);
ECPGlog
(
"out of memory
\n
"
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
lineno
);
return
false
;
}
(
*
stmt
)
->
command
=
query
;
(
*
stmt
)
->
lineno
=
lineno
;
list
=
&
((
*
stmt
)
->
inlist
);
type
=
va_arg
(
ap
,
enum
ECPGttype
);
while
(
type
!=
ECPGt_EORT
)
{
if
(
type
==
ECPGt_EOIT
)
{
list
=
&
((
*
stmt
)
->
outlist
);
}
else
{
struct
variable
*
var
,
*
ptr
;
var
=
malloc
(
sizeof
(
struct
variable
));
if
(
!
var
)
{
ECPGfinish
(
actual_connection
);
ECPGlog
(
"out of memory
\n
"
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
lineno
);
return
false
;
}
var
->
type
=
type
;
var
->
value
=
va_arg
(
ap
,
void
*
);
var
->
varcharsize
=
va_arg
(
ap
,
long
);
var
->
arrsize
=
va_arg
(
ap
,
long
);
var
->
offset
=
va_arg
(
ap
,
long
);
var
->
ind_type
=
va_arg
(
ap
,
enum
ECPGttype
);
var
->
ind_value
=
va_arg
(
ap
,
void
*
);
var
->
ind_varcharsize
=
va_arg
(
ap
,
long
);
var
->
ind_arrsize
=
va_arg
(
ap
,
long
);
var
->
ind_offset
=
va_arg
(
ap
,
long
);
var
->
next
=
NULL
;
for
(
ptr
=
*
list
;
ptr
&&
ptr
->
next
;
ptr
=
ptr
->
next
);
if
(
ptr
==
NULL
)
*
list
=
var
;
else
ptr
->
next
=
var
;
}
type
=
va_arg
(
ap
,
enum
ECPGttype
);
}
return
(
true
);
}
static
bool
ECPGexecute
(
struct
statement
*
stmt
)
{
{
va_list
ap
;
bool
status
=
false
;
bool
status
=
false
;
char
*
copiedquery
;
char
*
copiedquery
;
PGresult
*
results
;
PGresult
*
results
;
PGnotify
*
notify
;
PGnotify
*
notify
;
enum
ECPGttype
type
;
struct
variable
*
var
;
void
*
value
=
NULL
,
*
ind_value
;
long
varcharsize
,
ind_varcharsize
;
long
arrsize
,
ind_arrsize
;
long
offset
,
ind_offset
;
enum
ECPGttype
ind_type
;
memset
((
char
*
)
&
sqlca
,
0
,
sizeof
(
sqlca
));
memset
((
char
*
)
&
sqlca
,
0
,
sizeof
(
sqlca
));
va_start
(
ap
,
query
);
copiedquery
=
strdup
(
query
);
copiedquery
=
strdup
(
stmt
->
command
);
type
=
va_arg
(
ap
,
enum
ECPGttype
);
/*
/*
* Now, if the type is one of the fill in types then we take the
* Now, if the type is one of the fill in types then we take the
...
@@ -144,7 +227,8 @@ ECPGdo(int lineno, char *query,...)
...
@@ -144,7 +227,8 @@ ECPGdo(int lineno, char *query,...)
* Then if there are any more fill in types we fill in at the next and
* Then if there are any more fill in types we fill in at the next and
* so on.
* so on.
*/
*/
while
(
type
!=
ECPGt_EOIT
)
var
=
stmt
->
inlist
;
while
(
var
)
{
{
char
*
newcopy
;
char
*
newcopy
;
char
*
mallocedval
=
NULL
;
char
*
mallocedval
=
NULL
;
...
@@ -158,34 +242,24 @@ ECPGdo(int lineno, char *query,...)
...
@@ -158,34 +242,24 @@ ECPGdo(int lineno, char *query,...)
* think).
* think).
*/
*/
value
=
va_arg
(
ap
,
void
*
);
varcharsize
=
va_arg
(
ap
,
long
);
arrsize
=
va_arg
(
ap
,
long
);
offset
=
va_arg
(
ap
,
long
);
ind_type
=
va_arg
(
ap
,
enum
ECPGttype
);
ind_value
=
va_arg
(
ap
,
void
*
);
ind_varcharsize
=
va_arg
(
ap
,
long
);
ind_arrsize
=
va_arg
(
ap
,
long
);
ind_offset
=
va_arg
(
ap
,
long
);
buff
[
0
]
=
'\0'
;
buff
[
0
]
=
'\0'
;
/* check for null value and set input buffer accordingly */
/* check for null value and set input buffer accordingly */
switch
(
ind_type
)
switch
(
var
->
ind_type
)
{
{
case
ECPGt_short
:
case
ECPGt_short
:
case
ECPGt_unsigned_short
:
case
ECPGt_unsigned_short
:
if
(
*
(
short
*
)
ind_value
<
0
)
if
(
*
(
short
*
)
var
->
ind_value
<
0
)
strcpy
(
buff
,
"null"
);
strcpy
(
buff
,
"null"
);
break
;
break
;
case
ECPGt_int
:
case
ECPGt_int
:
case
ECPGt_unsigned_int
:
case
ECPGt_unsigned_int
:
if
(
*
(
int
*
)
ind_value
<
0
)
if
(
*
(
int
*
)
var
->
ind_value
<
0
)
strcpy
(
buff
,
"null"
);
strcpy
(
buff
,
"null"
);
break
;
break
;
case
ECPGt_long
:
case
ECPGt_long
:
case
ECPGt_unsigned_long
:
case
ECPGt_unsigned_long
:
if
(
*
(
long
*
)
ind_value
<
0L
)
if
(
*
(
long
*
)
var
->
ind_value
<
0L
)
strcpy
(
buff
,
"null"
);
strcpy
(
buff
,
"null"
);
break
;
break
;
default:
default:
...
@@ -194,42 +268,42 @@ ECPGdo(int lineno, char *query,...)
...
@@ -194,42 +268,42 @@ ECPGdo(int lineno, char *query,...)
if
(
*
buff
==
'\0'
)
if
(
*
buff
==
'\0'
)
{
{
switch
(
type
)
switch
(
var
->
type
)
{
{
case
ECPGt_short
:
case
ECPGt_short
:
case
ECPGt_int
:
case
ECPGt_int
:
sprintf
(
buff
,
"%d"
,
*
(
int
*
)
value
);
sprintf
(
buff
,
"%d"
,
*
(
int
*
)
va
r
->
va
lue
);
tobeinserted
=
buff
;
tobeinserted
=
buff
;
break
;
break
;
case
ECPGt_unsigned_short
:
case
ECPGt_unsigned_short
:
case
ECPGt_unsigned_int
:
case
ECPGt_unsigned_int
:
sprintf
(
buff
,
"%d"
,
*
(
unsigned
int
*
)
value
);
sprintf
(
buff
,
"%d"
,
*
(
unsigned
int
*
)
va
r
->
va
lue
);
tobeinserted
=
buff
;
tobeinserted
=
buff
;
break
;
break
;
case
ECPGt_long
:
case
ECPGt_long
:
sprintf
(
buff
,
"%ld"
,
*
(
long
*
)
value
);
sprintf
(
buff
,
"%ld"
,
*
(
long
*
)
va
r
->
va
lue
);
tobeinserted
=
buff
;
tobeinserted
=
buff
;
break
;
break
;
case
ECPGt_unsigned_long
:
case
ECPGt_unsigned_long
:
sprintf
(
buff
,
"%ld"
,
*
(
unsigned
long
*
)
value
);
sprintf
(
buff
,
"%ld"
,
*
(
unsigned
long
*
)
va
r
->
va
lue
);
tobeinserted
=
buff
;
tobeinserted
=
buff
;
break
;
break
;
case
ECPGt_float
:
case
ECPGt_float
:
sprintf
(
buff
,
"%.14g"
,
*
(
float
*
)
value
);
sprintf
(
buff
,
"%.14g"
,
*
(
float
*
)
va
r
->
va
lue
);
tobeinserted
=
buff
;
tobeinserted
=
buff
;
break
;
break
;
case
ECPGt_double
:
case
ECPGt_double
:
sprintf
(
buff
,
"%.14g"
,
*
(
double
*
)
value
);
sprintf
(
buff
,
"%.14g"
,
*
(
double
*
)
va
r
->
va
lue
);
tobeinserted
=
buff
;
tobeinserted
=
buff
;
break
;
break
;
case
ECPGt_bool
:
case
ECPGt_bool
:
sprintf
(
buff
,
"'%c'"
,
(
*
(
char
*
)
value
?
't'
:
'f'
));
sprintf
(
buff
,
"'%c'"
,
(
*
(
char
*
)
va
r
->
va
lue
?
't'
:
'f'
));
tobeinserted
=
buff
;
tobeinserted
=
buff
;
break
;
break
;
...
@@ -237,7 +311,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -237,7 +311,7 @@ ECPGdo(int lineno, char *query,...)
case
ECPGt_unsigned_char
:
case
ECPGt_unsigned_char
:
{
{
/* set slen to string length if type is char * */
/* set slen to string length if type is char * */
int
slen
=
(
var
charsize
==
0
)
?
strlen
((
char
*
)
value
)
:
varcharsize
;
int
slen
=
(
var
->
varcharsize
==
0
)
?
strlen
((
char
*
)
var
->
value
)
:
var
->
varcharsize
;
char
*
tmp
;
char
*
tmp
;
newcopy
=
(
char
*
)
malloc
(
slen
+
1
);
newcopy
=
(
char
*
)
malloc
(
slen
+
1
);
...
@@ -245,11 +319,11 @@ ECPGdo(int lineno, char *query,...)
...
@@ -245,11 +319,11 @@ ECPGdo(int lineno, char *query,...)
{
{
ECPGfinish
(
actual_connection
);
ECPGfinish
(
actual_connection
);
ECPGlog
(
"out of memory
\n
"
);
ECPGlog
(
"out of memory
\n
"
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
lineno
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
stmt
->
lineno
);
return
false
;
return
false
;
}
}
strncpy
(
newcopy
,
(
char
*
)
value
,
slen
);
strncpy
(
newcopy
,
(
char
*
)
va
r
->
va
lue
,
slen
);
newcopy
[
slen
]
=
'\0'
;
newcopy
[
slen
]
=
'\0'
;
mallocedval
=
(
char
*
)
malloc
(
2
*
strlen
(
newcopy
)
+
3
);
mallocedval
=
(
char
*
)
malloc
(
2
*
strlen
(
newcopy
)
+
3
);
...
@@ -257,7 +331,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -257,7 +331,7 @@ ECPGdo(int lineno, char *query,...)
{
{
ECPGfinish
(
actual_connection
);
ECPGfinish
(
actual_connection
);
ECPGlog
(
"out of memory
\n
"
);
ECPGlog
(
"out of memory
\n
"
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
lineno
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
stmt
->
lineno
);
return
false
;
return
false
;
}
}
...
@@ -267,7 +341,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -267,7 +341,7 @@ ECPGdo(int lineno, char *query,...)
{
{
ECPGfinish
(
actual_connection
);
ECPGfinish
(
actual_connection
);
ECPGlog
(
"out of memory
\n
"
);
ECPGlog
(
"out of memory
\n
"
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
lineno
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
stmt
->
lineno
);
return
false
;
return
false
;
}
}
...
@@ -282,28 +356,28 @@ ECPGdo(int lineno, char *query,...)
...
@@ -282,28 +356,28 @@ ECPGdo(int lineno, char *query,...)
case
ECPGt_varchar
:
case
ECPGt_varchar
:
{
{
struct
ECPGgeneric_varchar
*
var
=
struct
ECPGgeneric_varchar
*
var
iable
=
(
struct
ECPGgeneric_varchar
*
)
value
;
(
struct
ECPGgeneric_varchar
*
)
(
var
->
value
)
;
char
*
tmp
;
char
*
tmp
;
newcopy
=
(
char
*
)
malloc
(
var
->
len
+
1
);
newcopy
=
(
char
*
)
malloc
(
var
iable
->
len
+
1
);
if
(
!
newcopy
)
if
(
!
newcopy
)
{
{
ECPGfinish
(
actual_connection
);
ECPGfinish
(
actual_connection
);
ECPGlog
(
"out of memory
\n
"
);
ECPGlog
(
"out of memory
\n
"
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
lineno
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
stmt
->
lineno
);
return
false
;
return
false
;
}
}
strncpy
(
newcopy
,
var
->
arr
,
var
->
len
);
strncpy
(
newcopy
,
var
iable
->
arr
,
variable
->
len
);
newcopy
[
var
->
len
]
=
'\0'
;
newcopy
[
var
iable
->
len
]
=
'\0'
;
mallocedval
=
(
char
*
)
malloc
(
2
*
strlen
(
newcopy
)
+
3
);
mallocedval
=
(
char
*
)
malloc
(
2
*
strlen
(
newcopy
)
+
3
);
if
(
!
mallocedval
)
if
(
!
mallocedval
)
{
{
ECPGfinish
(
actual_connection
);
ECPGfinish
(
actual_connection
);
ECPGlog
(
"out of memory
\n
"
);
ECPGlog
(
"out of memory
\n
"
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
lineno
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
stmt
->
lineno
);
return
false
;
return
false
;
}
}
...
@@ -313,7 +387,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -313,7 +387,7 @@ ECPGdo(int lineno, char *query,...)
{
{
ECPGfinish
(
actual_connection
);
ECPGfinish
(
actual_connection
);
ECPGlog
(
"out of memory
\n
"
);
ECPGlog
(
"out of memory
\n
"
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
lineno
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
stmt
->
lineno
);
return
false
;
return
false
;
}
}
...
@@ -329,7 +403,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -329,7 +403,7 @@ ECPGdo(int lineno, char *query,...)
default:
default:
/* Not implemented yet */
/* Not implemented yet */
register_error
(
ECPG_UNSUPPORTED
,
"Unsupported type %s on line %d."
,
register_error
(
ECPG_UNSUPPORTED
,
"Unsupported type %s on line %d."
,
ECPGtype_name
(
type
),
lineno
);
ECPGtype_name
(
var
->
type
),
stmt
->
lineno
);
return
false
;
return
false
;
break
;
break
;
}
}
...
@@ -348,7 +422,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -348,7 +422,7 @@ ECPGdo(int lineno, char *query,...)
{
{
ECPGfinish
(
actual_connection
);
ECPGfinish
(
actual_connection
);
ECPGlog
(
"out of memory
\n
"
);
ECPGlog
(
"out of memory
\n
"
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
lineno
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
stmt
->
lineno
);
return
false
;
return
false
;
}
}
...
@@ -360,7 +434,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -360,7 +434,7 @@ ECPGdo(int lineno, char *query,...)
* We have an argument but we dont have the matched up string
* We have an argument but we dont have the matched up string
* in the string
* in the string
*/
*/
register_error
(
ECPG_TOO_MANY_ARGUMENTS
,
"Too many arguments line %d."
,
lineno
);
register_error
(
ECPG_TOO_MANY_ARGUMENTS
,
"Too many arguments line %d."
,
stmt
->
lineno
);
return
false
;
return
false
;
}
}
else
else
...
@@ -379,7 +453,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -379,7 +453,7 @@ ECPGdo(int lineno, char *query,...)
/*
/*
* Now everything is safely copied to the newcopy. Lets free the
* Now everything is safely copied to the newcopy. Lets free the
* oldcopy and let the copiedquery get the value from the newcopy.
* oldcopy and let the copiedquery get the va
r->va
lue from the newcopy.
*/
*/
if
(
mallocedval
!=
NULL
)
if
(
mallocedval
!=
NULL
)
{
{
...
@@ -390,13 +464,13 @@ ECPGdo(int lineno, char *query,...)
...
@@ -390,13 +464,13 @@ ECPGdo(int lineno, char *query,...)
free
(
copiedquery
);
free
(
copiedquery
);
copiedquery
=
newcopy
;
copiedquery
=
newcopy
;
type
=
va_arg
(
ap
,
enum
ECPGttype
)
;
var
=
var
->
next
;
}
}
/* Check if there are unmatched things left. */
/* Check if there are unmatched things left. */
if
(
strstr
(
copiedquery
,
";;"
)
!=
NULL
)
if
(
strstr
(
copiedquery
,
";;"
)
!=
NULL
)
{
{
register_error
(
ECPG_TOO_FEW_ARGUMENTS
,
"Too few arguments line %d."
,
lineno
);
register_error
(
ECPG_TOO_FEW_ARGUMENTS
,
"Too few arguments line %d."
,
stmt
->
lineno
);
return
false
;
return
false
;
}
}
...
@@ -406,27 +480,28 @@ ECPGdo(int lineno, char *query,...)
...
@@ -406,27 +480,28 @@ ECPGdo(int lineno, char *query,...)
{
{
if
((
results
=
PQexec
(
actual_connection
->
connection
,
"begin transaction"
))
==
NULL
)
if
((
results
=
PQexec
(
actual_connection
->
connection
,
"begin transaction"
))
==
NULL
)
{
{
register_error
(
ECPG_TRANS
,
"Error starting transaction line %d."
,
lineno
);
register_error
(
ECPG_TRANS
,
"Error starting transaction line %d."
,
stmt
->
lineno
);
return
false
;
return
false
;
}
}
PQclear
(
results
);
PQclear
(
results
);
committed
=
0
;
committed
=
0
;
}
}
ECPGlog
(
"ECPG
do line %d: QUERY: %s
\n
"
,
lineno
,
copiedquery
);
ECPGlog
(
"ECPG
execute line %d: QUERY: %s
\n
"
,
stmt
->
lineno
,
copiedquery
);
results
=
PQexec
(
actual_connection
->
connection
,
copiedquery
);
results
=
PQexec
(
actual_connection
->
connection
,
copiedquery
);
free
(
copiedquery
);
free
(
copiedquery
);
if
(
results
==
NULL
)
if
(
results
==
NULL
)
{
{
ECPGlog
(
"ECPG
do line %d: error: %s"
,
lineno
,
ECPGlog
(
"ECPG
execute line %d: error: %s"
,
stmt
->
lineno
,
PQerrorMessage
(
actual_connection
->
connection
));
PQerrorMessage
(
actual_connection
->
connection
));
register_error
(
ECPG_PGSQL
,
"Postgres error: %s line %d."
,
register_error
(
ECPG_PGSQL
,
"Postgres error: %s line %d."
,
PQerrorMessage
(
actual_connection
->
connection
),
lineno
);
PQerrorMessage
(
actual_connection
->
connection
),
stmt
->
lineno
);
}
}
else
else
{
{
sqlca
.
sqlerrd
[
2
]
=
0
;
sqlca
.
sqlerrd
[
2
]
=
0
;
var
=
stmt
->
outlist
;
switch
(
PQresultStatus
(
results
))
switch
(
PQresultStatus
(
results
))
{
{
int
nfields
,
ntuples
,
act_tuple
,
act_field
;
int
nfields
,
ntuples
,
act_tuple
,
act_field
;
...
@@ -445,9 +520,9 @@ ECPGdo(int lineno, char *query,...)
...
@@ -445,9 +520,9 @@ ECPGdo(int lineno, char *query,...)
if
(
ntuples
<
1
)
if
(
ntuples
<
1
)
{
{
ECPGlog
(
"ECPG
do
line %d: Incorrect number of matches: %d
\n
"
,
ECPGlog
(
"ECPG
execute
line %d: Incorrect number of matches: %d
\n
"
,
lineno
,
ntuples
);
stmt
->
lineno
,
ntuples
);
register_error
(
ECPG_NOT_FOUND
,
"Data not found line %d."
,
lineno
);
register_error
(
ECPG_NOT_FOUND
,
"Data not found line %d."
,
stmt
->
lineno
);
status
=
false
;
status
=
false
;
break
;
break
;
}
}
...
@@ -457,23 +532,19 @@ ECPGdo(int lineno, char *query,...)
...
@@ -457,23 +532,19 @@ ECPGdo(int lineno, char *query,...)
char
*
pval
;
char
*
pval
;
char
*
scan_length
;
char
*
scan_length
;
type
=
va_arg
(
ap
,
enum
ECPGttype
);
if
(
var
==
NULL
)
value
=
va_arg
(
ap
,
void
*
);
{
varcharsize
=
va_arg
(
ap
,
long
);
ECPGlog
(
"ECPGexecute line %d: Too few arguments.
\n
"
,
stmt
->
lineno
);
arrsize
=
va_arg
(
ap
,
long
);
register_error
(
ECPG_TOO_FEW_ARGUMENTS
,
"Too few arguments line %d."
,
stmt
->
lineno
);
offset
=
va_arg
(
ap
,
long
);
return
(
false
);
ind_type
=
va_arg
(
ap
,
enum
ECPGttype
);
}
ind_value
=
va_arg
(
ap
,
void
*
);
ind_varcharsize
=
va_arg
(
ap
,
long
);
ind_arrsize
=
va_arg
(
ap
,
long
);
ind_offset
=
va_arg
(
ap
,
long
);
/* if we don't have enough space, we cannot read all tuples */
/* if we don't have enough space, we cannot read all tuples */
if
((
arrsize
>
0
&&
ntuples
>
arrsize
)
||
(
ind_arrsize
>
0
&&
ntuples
>
ind_arrsize
))
if
((
var
->
arrsize
>
0
&&
ntuples
>
var
->
arrsize
)
||
(
var
->
ind_arrsize
>
0
&&
ntuples
>
var
->
ind_arrsize
))
{
{
ECPGlog
(
"ECPG
do
line %d: Incorrect number of matches: %d don't fit into array of %d
\n
"
,
ECPGlog
(
"ECPG
execute
line %d: Incorrect number of matches: %d don't fit into array of %d
\n
"
,
lineno
,
ntuples
,
arrsize
);
stmt
->
lineno
,
ntuples
,
var
->
arrsize
);
register_error
(
ECPG_TOO_MANY_MATCHES
,
"Too many matches line %d."
,
lineno
);
register_error
(
ECPG_TOO_MANY_MATCHES
,
"Too many matches line %d."
,
stmt
->
lineno
);
status
=
false
;
status
=
false
;
break
;
break
;
}
}
...
@@ -481,31 +552,31 @@ ECPGdo(int lineno, char *query,...)
...
@@ -481,31 +552,31 @@ ECPGdo(int lineno, char *query,...)
{
{
pval
=
PQgetvalue
(
results
,
act_tuple
,
act_field
);
pval
=
PQgetvalue
(
results
,
act_tuple
,
act_field
);
ECPGlog
(
"ECPG
do line %d: RESULT: %s
\n
"
,
lineno
,
pval
?
pval
:
""
);
ECPGlog
(
"ECPG
execute line %d: RESULT: %s
\n
"
,
stmt
->
lineno
,
pval
?
pval
:
""
);
/* Now the pval is a pointer to the value. */
/* Now the pval is a pointer to the va
r->va
lue. */
/* We will have to decode the value */
/* We will have to decode the va
r->va
lue */
/* check for null value and set indicator accordingly */
/* check for null va
r->va
lue and set indicator accordingly */
switch
(
ind_type
)
switch
(
var
->
ind_type
)
{
{
case
ECPGt_short
:
case
ECPGt_short
:
case
ECPGt_unsigned_short
:
case
ECPGt_unsigned_short
:
((
short
*
)
ind_value
)[
act_tuple
]
=
-
PQgetisnull
(
results
,
act_tuple
,
act_field
);
((
short
*
)
var
->
ind_value
)[
act_tuple
]
=
-
PQgetisnull
(
results
,
act_tuple
,
act_field
);
break
;
break
;
case
ECPGt_int
:
case
ECPGt_int
:
case
ECPGt_unsigned_int
:
case
ECPGt_unsigned_int
:
((
int
*
)
ind_value
)[
act_tuple
]
=
-
PQgetisnull
(
results
,
act_tuple
,
act_field
);
((
int
*
)
var
->
ind_value
)[
act_tuple
]
=
-
PQgetisnull
(
results
,
act_tuple
,
act_field
);
break
;
break
;
case
ECPGt_long
:
case
ECPGt_long
:
case
ECPGt_unsigned_long
:
case
ECPGt_unsigned_long
:
((
long
*
)
ind_value
)[
act_tuple
]
=
-
PQgetisnull
(
results
,
act_tuple
,
act_field
);
((
long
*
)
var
->
ind_value
)[
act_tuple
]
=
-
PQgetisnull
(
results
,
act_tuple
,
act_field
);
break
;
break
;
default:
default:
break
;
break
;
}
}
switch
(
type
)
switch
(
var
->
type
)
{
{
long
res
;
long
res
;
unsigned
long
ures
;
unsigned
long
ures
;
...
@@ -520,7 +591,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -520,7 +591,7 @@ ECPGdo(int lineno, char *query,...)
if
(
*
scan_length
!=
'\0'
)
/* Garbage left */
if
(
*
scan_length
!=
'\0'
)
/* Garbage left */
{
{
register_error
(
ECPG_INT_FORMAT
,
"Not correctly formatted int type: %s line %d."
,
register_error
(
ECPG_INT_FORMAT
,
"Not correctly formatted int type: %s line %d."
,
pval
,
lineno
);
pval
,
stmt
->
lineno
);
status
=
false
;
status
=
false
;
res
=
0L
;
res
=
0L
;
}
}
...
@@ -529,16 +600,16 @@ ECPGdo(int lineno, char *query,...)
...
@@ -529,16 +600,16 @@ ECPGdo(int lineno, char *query,...)
res
=
0L
;
res
=
0L
;
/* Again?! Yes */
/* Again?! Yes */
switch
(
type
)
switch
(
var
->
type
)
{
{
case
ECPGt_short
:
case
ECPGt_short
:
((
short
*
)
value
)[
act_tuple
]
=
(
short
)
res
;
((
short
*
)
va
r
->
va
lue
)[
act_tuple
]
=
(
short
)
res
;
break
;
break
;
case
ECPGt_int
:
case
ECPGt_int
:
((
int
*
)
value
)[
act_tuple
]
=
(
int
)
res
;
((
int
*
)
va
r
->
va
lue
)[
act_tuple
]
=
(
int
)
res
;
break
;
break
;
case
ECPGt_long
:
case
ECPGt_long
:
((
long
*
)
value
)[
act_tuple
]
=
res
;
((
long
*
)
va
r
->
va
lue
)[
act_tuple
]
=
res
;
break
;
break
;
default:
default:
/* Cannot happen */
/* Cannot happen */
...
@@ -555,7 +626,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -555,7 +626,7 @@ ECPGdo(int lineno, char *query,...)
if
(
*
scan_length
!=
'\0'
)
/* Garbage left */
if
(
*
scan_length
!=
'\0'
)
/* Garbage left */
{
{
register_error
(
ECPG_UINT_FORMAT
,
"Not correctly formatted unsigned type: %s line %d."
,
register_error
(
ECPG_UINT_FORMAT
,
"Not correctly formatted unsigned type: %s line %d."
,
pval
,
lineno
);
pval
,
stmt
->
lineno
);
status
=
false
;
status
=
false
;
ures
=
0L
;
ures
=
0L
;
}
}
...
@@ -564,16 +635,16 @@ ECPGdo(int lineno, char *query,...)
...
@@ -564,16 +635,16 @@ ECPGdo(int lineno, char *query,...)
ures
=
0L
;
ures
=
0L
;
/* Again?! Yes */
/* Again?! Yes */
switch
(
type
)
switch
(
var
->
type
)
{
{
case
ECPGt_unsigned_short
:
case
ECPGt_unsigned_short
:
((
unsigned
short
*
)
value
)[
act_tuple
]
=
(
unsigned
short
)
ures
;
((
unsigned
short
*
)
va
r
->
va
lue
)[
act_tuple
]
=
(
unsigned
short
)
ures
;
break
;
break
;
case
ECPGt_unsigned_int
:
case
ECPGt_unsigned_int
:
((
unsigned
int
*
)
value
)[
act_tuple
]
=
(
unsigned
int
)
ures
;
((
unsigned
int
*
)
va
r
->
va
lue
)[
act_tuple
]
=
(
unsigned
int
)
ures
;
break
;
break
;
case
ECPGt_unsigned_long
:
case
ECPGt_unsigned_long
:
((
unsigned
long
*
)
value
)[
act_tuple
]
=
ures
;
((
unsigned
long
*
)
va
r
->
va
lue
)[
act_tuple
]
=
ures
;
break
;
break
;
default:
default:
/* Cannot happen */
/* Cannot happen */
...
@@ -590,7 +661,7 @@ ECPGdo(int lineno, char *query,...)
...
@@ -590,7 +661,7 @@ ECPGdo(int lineno, char *query,...)
if
(
*
scan_length
!=
'\0'
)
/* Garbage left */
if
(
*
scan_length
!=
'\0'
)
/* Garbage left */
{
{
register_error
(
ECPG_FLOAT_FORMAT
,
"Not correctly formatted floating point type: %s line %d."
,
register_error
(
ECPG_FLOAT_FORMAT
,
"Not correctly formatted floating point type: %s line %d."
,
pval
,
lineno
);
pval
,
stmt
->
lineno
);
status
=
false
;
status
=
false
;
dres
=
0
.
0
;
dres
=
0
.
0
;
}
}
...
@@ -599,13 +670,13 @@ ECPGdo(int lineno, char *query,...)
...
@@ -599,13 +670,13 @@ ECPGdo(int lineno, char *query,...)
dres
=
0
.
0
;
dres
=
0
.
0
;
/* Again?! Yes */
/* Again?! Yes */
switch
(
type
)
switch
(
var
->
type
)
{
{
case
ECPGt_float
:
case
ECPGt_float
:
((
float
*
)
value
)[
act_tuple
]
=
dres
;
((
float
*
)
va
r
->
va
lue
)[
act_tuple
]
=
dres
;
break
;
break
;
case
ECPGt_double
:
case
ECPGt_double
:
((
double
*
)
value
)[
act_tuple
]
=
dres
;
((
double
*
)
va
r
->
va
lue
)[
act_tuple
]
=
dres
;
break
;
break
;
default:
default:
/* Cannot happen */
/* Cannot happen */
...
@@ -618,50 +689,50 @@ ECPGdo(int lineno, char *query,...)
...
@@ -618,50 +689,50 @@ ECPGdo(int lineno, char *query,...)
{
{
if
(
pval
[
0
]
==
'f'
&&
pval
[
1
]
==
'\0'
)
if
(
pval
[
0
]
==
'f'
&&
pval
[
1
]
==
'\0'
)
{
{
((
char
*
)
value
)[
act_tuple
]
=
false
;
((
char
*
)
va
r
->
va
lue
)[
act_tuple
]
=
false
;
break
;
break
;
}
}
else
if
(
pval
[
0
]
==
't'
&&
pval
[
1
]
==
'\0'
)
else
if
(
pval
[
0
]
==
't'
&&
pval
[
1
]
==
'\0'
)
{
{
((
char
*
)
value
)[
act_tuple
]
=
true
;
((
char
*
)
va
r
->
va
lue
)[
act_tuple
]
=
true
;
break
;
break
;
}
}
}
}
register_error
(
ECPG_CONVERT_BOOL
,
"Unable to convert %s to bool on line %d."
,
register_error
(
ECPG_CONVERT_BOOL
,
"Unable to convert %s to bool on line %d."
,
(
pval
?
pval
:
"NULL"
),
(
pval
?
pval
:
"NULL"
),
lineno
);
stmt
->
lineno
);
status
=
false
;
status
=
false
;
break
;
break
;
case
ECPGt_char
:
case
ECPGt_char
:
case
ECPGt_unsigned_char
:
case
ECPGt_unsigned_char
:
{
{
if
(
varcharsize
==
0
)
if
(
var
->
var
charsize
==
0
)
{
{
/* char* */
/* char* */
strncpy
(((
char
**
)
value
)[
act_tuple
],
pval
,
strlen
(
pval
));
strncpy
(((
char
**
)
va
r
->
va
lue
)[
act_tuple
],
pval
,
strlen
(
pval
));
(((
char
**
)
value
)[
act_tuple
])[
strlen
(
pval
)]
=
'\0'
;
(((
char
**
)
va
r
->
va
lue
)[
act_tuple
])[
strlen
(
pval
)]
=
'\0'
;
}
}
else
else
{
{
strncpy
((
char
*
)
(
va
lue
+
offset
*
act_tuple
),
pval
,
varcharsize
);
strncpy
((
char
*
)
(
va
r
->
value
+
var
->
offset
*
act_tuple
),
pval
,
var
->
varcharsize
);
if
(
varcharsize
<
strlen
(
pval
))
if
(
var
->
var
charsize
<
strlen
(
pval
))
{
{
/* truncation */
/* truncation */
switch
(
ind_type
)
switch
(
var
->
ind_type
)
{
{
case
ECPGt_short
:
case
ECPGt_short
:
case
ECPGt_unsigned_short
:
case
ECPGt_unsigned_short
:
((
short
*
)
ind_value
)[
act_tuple
]
=
varcharsize
;
((
short
*
)
var
->
ind_value
)[
act_tuple
]
=
var
->
varcharsize
;
break
;
break
;
case
ECPGt_int
:
case
ECPGt_int
:
case
ECPGt_unsigned_int
:
case
ECPGt_unsigned_int
:
((
int
*
)
ind_value
)[
act_tuple
]
=
varcharsize
;
((
int
*
)
var
->
ind_value
)[
act_tuple
]
=
var
->
varcharsize
;
break
;
break
;
case
ECPGt_long
:
case
ECPGt_long
:
case
ECPGt_unsigned_long
:
case
ECPGt_unsigned_long
:
((
long
*
)
ind_value
)[
act_tuple
]
=
varcharsize
;
((
long
*
)
var
->
ind_value
)[
act_tuple
]
=
var
->
varcharsize
;
break
;
break
;
default:
default:
break
;
break
;
...
@@ -674,62 +745,55 @@ ECPGdo(int lineno, char *query,...)
...
@@ -674,62 +745,55 @@ ECPGdo(int lineno, char *query,...)
case
ECPGt_varchar
:
case
ECPGt_varchar
:
{
{
struct
ECPGgeneric_varchar
*
var
=
struct
ECPGgeneric_varchar
*
var
iable
=
(
struct
ECPGgeneric_varchar
*
)
(
va
lue
+
offset
*
act_tuple
);
(
struct
ECPGgeneric_varchar
*
)
(
va
r
->
value
+
var
->
offset
*
act_tuple
);
if
(
varcharsize
==
0
)
if
(
var
->
var
charsize
==
0
)
strncpy
(
var
->
arr
,
pval
,
strlen
(
pval
));
strncpy
(
var
iable
->
arr
,
pval
,
strlen
(
pval
));
else
else
strncpy
(
var
->
arr
,
pval
,
varcharsize
);
strncpy
(
var
iable
->
arr
,
pval
,
var
->
varcharsize
);
var
->
len
=
strlen
(
pval
);
var
iable
->
len
=
strlen
(
pval
);
if
(
var
charsize
>
0
&&
var
->
len
>
varcharsize
)
if
(
var
->
varcharsize
>
0
&&
variable
->
len
>
var
->
varcharsize
)
{
{
/* truncation */
/* truncation */
switch
(
ind_type
)
switch
(
var
->
ind_type
)
{
{
case
ECPGt_short
:
case
ECPGt_short
:
case
ECPGt_unsigned_short
:
case
ECPGt_unsigned_short
:
((
short
*
)
ind_value
)[
act_tuple
]
=
varcharsize
;
((
short
*
)
var
->
ind_value
)[
act_tuple
]
=
var
->
varcharsize
;
break
;
break
;
case
ECPGt_int
:
case
ECPGt_int
:
case
ECPGt_unsigned_int
:
case
ECPGt_unsigned_int
:
((
int
*
)
ind_value
)[
act_tuple
]
=
varcharsize
;
((
int
*
)
var
->
ind_value
)[
act_tuple
]
=
var
->
varcharsize
;
break
;
break
;
case
ECPGt_long
:
case
ECPGt_long
:
case
ECPGt_unsigned_long
:
case
ECPGt_unsigned_long
:
((
long
*
)
ind_value
)[
act_tuple
]
=
varcharsize
;
((
long
*
)
var
->
ind_value
)[
act_tuple
]
=
var
->
varcharsize
;
break
;
break
;
default:
default:
break
;
break
;
}
}
sqlca
.
sqlwarn
[
0
]
=
sqlca
.
sqlwarn
[
1
]
=
'W'
;
sqlca
.
sqlwarn
[
0
]
=
sqlca
.
sqlwarn
[
1
]
=
'W'
;
var
->
len
=
varcharsize
;
var
iable
->
len
=
var
->
varcharsize
;
}
}
}
}
break
;
break
;
case
ECPGt_EORT
:
ECPGlog
(
"ECPGdo line %d: Too few arguments.
\n
"
,
lineno
);
register_error
(
ECPG_TOO_FEW_ARGUMENTS
,
"Too few arguments line %d."
,
lineno
);
status
=
false
;
break
;
default:
default:
register_error
(
ECPG_UNSUPPORTED
,
"Unsupported type %s on line %d."
,
register_error
(
ECPG_UNSUPPORTED
,
"Unsupported type %s on line %d."
,
ECPGtype_name
(
type
),
lineno
);
ECPGtype_name
(
var
->
type
),
stmt
->
lineno
);
status
=
false
;
status
=
false
;
break
;
break
;
}
}
}
}
var
=
var
->
next
;
}
}
type
=
va_arg
(
ap
,
enum
ECPGttype
);
if
(
status
&&
var
!=
NULL
)
if
(
status
&&
type
!=
ECPGt_EORT
)
{
{
register_error
(
ECPG_TOO_MANY_ARGUMENTS
,
"Too many arguments line %d."
,
lineno
);
register_error
(
ECPG_TOO_MANY_ARGUMENTS
,
"Too many arguments line %d."
,
stmt
->
lineno
);
status
=
false
;
status
=
false
;
}
}
...
@@ -737,35 +801,34 @@ ECPGdo(int lineno, char *query,...)
...
@@ -737,35 +801,34 @@ ECPGdo(int lineno, char *query,...)
break
;
break
;
case
PGRES_EMPTY_QUERY
:
case
PGRES_EMPTY_QUERY
:
/* do nothing */
/* do nothing */
register_error
(
ECPG_EMPTY
,
"Empty query line %d."
,
lineno
);
register_error
(
ECPG_EMPTY
,
"Empty query line %d."
,
stmt
->
lineno
);
break
;
break
;
case
PGRES_COMMAND_OK
:
case
PGRES_COMMAND_OK
:
status
=
true
;
status
=
true
;
sqlca
.
sqlerrd
[
2
]
=
atol
(
PQcmdTuples
(
results
));
sqlca
.
sqlerrd
[
2
]
=
atol
(
PQcmdTuples
(
results
));
ECPGlog
(
"TEST: %s
\n
"
,
PQcmdTuples
(
results
));
ECPGlog
(
"ECPGexecute line %d Ok: %s
\n
"
,
stmt
->
lineno
,
PQcmdStatus
(
results
));
ECPGlog
(
"ECPGdo line %d Ok: %s
\n
"
,
lineno
,
PQcmdStatus
(
results
));
break
;
break
;
case
PGRES_NONFATAL_ERROR
:
case
PGRES_NONFATAL_ERROR
:
case
PGRES_FATAL_ERROR
:
case
PGRES_FATAL_ERROR
:
case
PGRES_BAD_RESPONSE
:
case
PGRES_BAD_RESPONSE
:
ECPGlog
(
"ECPG
do
line %d: Error: %s"
,
ECPGlog
(
"ECPG
execute
line %d: Error: %s"
,
lineno
,
PQerrorMessage
(
actual_connection
->
connection
));
stmt
->
lineno
,
PQerrorMessage
(
actual_connection
->
connection
));
register_error
(
ECPG_PGSQL
,
"Error: %s line %d."
,
register_error
(
ECPG_PGSQL
,
"Error: %s line %d."
,
PQerrorMessage
(
actual_connection
->
connection
),
lineno
);
PQerrorMessage
(
actual_connection
->
connection
),
stmt
->
lineno
);
status
=
false
;
status
=
false
;
break
;
break
;
case
PGRES_COPY_OUT
:
case
PGRES_COPY_OUT
:
ECPGlog
(
"ECPG
do line %d: Got PGRES_COPY_OUT ... tossing.
\n
"
,
lineno
);
ECPGlog
(
"ECPG
execute line %d: Got PGRES_COPY_OUT ... tossing.
\n
"
,
stmt
->
lineno
);
PQendcopy
(
results
->
conn
);
PQendcopy
(
results
->
conn
);
break
;
break
;
case
PGRES_COPY_IN
:
case
PGRES_COPY_IN
:
ECPGlog
(
"ECPG
do line %d: Got PGRES_COPY_IN ... tossing.
\n
"
,
lineno
);
ECPGlog
(
"ECPG
execute line %d: Got PGRES_COPY_IN ... tossing.
\n
"
,
stmt
->
lineno
);
PQendcopy
(
results
->
conn
);
PQendcopy
(
results
->
conn
);
break
;
break
;
default:
default:
ECPGlog
(
"ECPG
do
line %d: Got something else, postgres error.
\n
"
,
ECPGlog
(
"ECPG
execute
line %d: Got something else, postgres error.
\n
"
,
lineno
);
stmt
->
lineno
);
register_error
(
ECPG_PGSQL
,
"Postgres error line %d."
,
lineno
);
register_error
(
ECPG_PGSQL
,
"Postgres error line %d."
,
stmt
->
lineno
);
status
=
false
;
status
=
false
;
break
;
break
;
}
}
...
@@ -775,8 +838,8 @@ ECPGdo(int lineno, char *query,...)
...
@@ -775,8 +838,8 @@ ECPGdo(int lineno, char *query,...)
notify
=
PQnotifies
(
actual_connection
->
connection
);
notify
=
PQnotifies
(
actual_connection
->
connection
);
if
(
notify
)
if
(
notify
)
{
{
ECPGlog
(
"ECPG
do
line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received
\n
"
,
ECPGlog
(
"ECPG
execute
line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received
\n
"
,
lineno
,
notify
->
relname
,
notify
->
be_pid
);
stmt
->
lineno
,
notify
->
relname
,
notify
->
be_pid
);
free
(
notify
);
free
(
notify
);
}
}
...
@@ -784,6 +847,20 @@ ECPGdo(int lineno, char *query,...)
...
@@ -784,6 +847,20 @@ ECPGdo(int lineno, char *query,...)
return
status
;
return
status
;
}
}
bool
ECPGdo
(
int
lineno
,
char
*
query
,
...)
{
va_list
args
;
struct
statement
*
stmt
;
va_start
(
args
,
query
);
if
(
create_statement
(
lineno
,
&
stmt
,
query
,
args
)
==
false
)
return
(
false
);
va_end
(
args
);
return
(
ECPGexecute
(
stmt
));
}
bool
bool
ECPGtrans
(
int
lineno
,
const
char
*
transaction
)
ECPGtrans
(
int
lineno
,
const
char
*
transaction
)
...
@@ -940,56 +1017,3 @@ sqlprint(void)
...
@@ -940,56 +1017,3 @@ sqlprint(void)
sqlca
.
sqlerrm
.
sqlerrmc
[
sqlca
.
sqlerrm
.
sqlerrml
]
=
'\0'
;
sqlca
.
sqlerrm
.
sqlerrmc
[
sqlca
.
sqlerrm
.
sqlerrml
]
=
'\0'
;
printf
(
"sql error %s
\n
"
,
sqlca
.
sqlerrm
.
sqlerrmc
);
printf
(
"sql error %s
\n
"
,
sqlca
.
sqlerrm
.
sqlerrmc
);
}
}
/* keep a list of cursors */
struct
cursor
*
cur
=
NULL
;
bool
ECPGdeclare
(
int
lineno
,
const
char
*
name
,
char
*
command
)
{
struct
cursor
*
ptr
;
for
(
ptr
=
cur
;
ptr
!=
NULL
;
ptr
=
ptr
->
next
)
{
if
(
strcmp
(
name
,
ptr
->
name
)
==
0
)
{
/* re-definition */
free
(
ptr
->
command
);
ptr
->
command
=
command
;
break
;
}
}
if
(
ptr
==
NULL
)
{
struct
cursor
*
this
=
(
struct
cursor
*
)
malloc
(
sizeof
(
struct
cursor
));
if
(
!
this
)
{
ECPGlog
(
"out of memory
\n
"
);
register_error
(
ECPG_OUT_OF_MEMORY
,
"out of memory in line %d"
,
lineno
);
return
false
;
}
/* initial definition */
this
->
next
=
cur
;
this
->
name
=
name
;
this
->
command
=
command
;
cur
=
this
;
}
return
(
true
);
}
bool
ECPGopen
(
int
lineno
,
const
char
*
name
)
{
struct
cursor
*
ptr
;
for
(
ptr
=
cur
;
ptr
!=
NULL
;
ptr
=
ptr
->
next
)
{
if
(
strcmp
(
ptr
->
name
,
name
)
==
0
)
return
(
ECPGdo
(
lineno
,
ptr
->
command
,
ECPGt_EOIT
,
ECPGt_EORT
));
}
ECPGlog
(
"trying to open undeclared cursor %s
\n
"
,
name
);
register_error
(
ECPG_UNDECLARED_CURSOR
,
"trying to open undeclared cursor %s in line %d"
,
name
,
lineno
);
return
(
false
);
}
src/interfaces/ecpg/preproc/ecpg.c
View file @
c6dd1e63
...
@@ -23,6 +23,7 @@ extern char *optarg;
...
@@ -23,6 +23,7 @@ extern char *optarg;
struct
_include_path
*
include_paths
;
struct
_include_path
*
include_paths
;
static
int
no_auto_trans
=
0
;
static
int
no_auto_trans
=
0
;
struct
cursor
*
cur
=
NULL
;
static
void
static
void
usage
(
char
*
progname
)
usage
(
char
*
progname
)
...
@@ -138,6 +139,24 @@ main(int argc, char *const argv[])
...
@@ -138,6 +139,24 @@ main(int argc, char *const argv[])
{
{
struct
cursor
*
ptr
;
struct
cursor
*
ptr
;
/* remove old cursor definitions if any are still there */
for
(
ptr
=
cur
;
ptr
!=
NULL
;
ptr
=
ptr
->
next
)
{
struct
arguments
*
l1
,
*
l2
;
free
(
ptr
->
command
);
free
(
ptr
->
name
);
for
(
l1
=
argsinsert
;
l1
;
l1
=
l2
)
{
l2
=
l1
->
next
;
free
(
l1
);
}
for
(
l1
=
argsresult
;
l1
;
l1
=
l2
)
{
l2
=
l1
->
next
;
free
(
l1
);
}
}
/* initialize lex */
/* initialize lex */
lex_init
();
lex_init
();
...
...
src/interfaces/ecpg/preproc/extern.h
View file @
c6dd1e63
...
@@ -16,6 +16,15 @@ struct _include_path { char * path;
...
@@ -16,6 +16,15 @@ struct _include_path { char * path;
extern
struct
_include_path
*
include_paths
;
extern
struct
_include_path
*
include_paths
;
struct
cursor
{
char
*
name
;
char
*
command
;
struct
arguments
*
argsinsert
;
struct
arguments
*
argsresult
;
struct
cursor
*
next
;
};
extern
struct
cursor
*
cur
;
/* This is a linked list of the variable names and types. */
/* This is a linked list of the variable names and types. */
struct
variable
struct
variable
{
{
...
@@ -28,6 +37,15 @@ struct variable
...
@@ -28,6 +37,15 @@ struct variable
extern
struct
ECPGtype
ecpg_no_indicator
;
extern
struct
ECPGtype
ecpg_no_indicator
;
extern
struct
variable
no_indicator
;
extern
struct
variable
no_indicator
;
struct
arguments
{
struct
variable
*
variable
;
struct
variable
*
indicator
;
struct
arguments
*
next
;
};
extern
struct
arguments
*
argsinsert
;
extern
struct
arguments
*
argsresult
;
/* functions */
/* functions */
extern
void
lex_init
(
void
);
extern
void
lex_init
(
void
);
...
...
src/interfaces/ecpg/preproc/preproc.y
View file @
c6dd1e63
...
@@ -245,14 +245,9 @@ remove_variables(int brace_level)
...
@@ -245,14 +245,9 @@ remove_variables(int brace_level)
* These are of two kinds: input and output.
* These are of two kinds: input and output.
* I will make two lists for them.
* I will make two lists for them.
*/
*/
struct arguments {
struct variable * variable;
struct variable * indicator;
struct arguments * next;
};
st
atic st
ruct arguments * argsinsert = NULL;
struct arguments * argsinsert = NULL;
st
atic st
ruct arguments * argsresult = NULL;
struct arguments * argsresult = NULL;
static void
static void
reset_variables(void)
reset_variables(void)
...
@@ -279,7 +274,7 @@ add_variable(struct arguments ** list, struct variable * var, struct variable *
...
@@ -279,7 +274,7 @@ add_variable(struct arguments ** list, struct variable * var, struct variable *
deletes the list as we go on.
deletes the list as we go on.
*/
*/
static void
static void
dump_variables(struct arguments * list)
dump_variables(struct arguments * list
, int mode
)
{
{
if (list == NULL)
if (list == NULL)
{
{
...
@@ -290,7 +285,7 @@ dump_variables(struct arguments * list)
...
@@ -290,7 +285,7 @@ dump_variables(struct arguments * list)
end of the list:
end of the list:
*/
*/
dump_variables(list->next);
dump_variables(list->next
, mode
);
/* Then the current element and its indicator */
/* Then the current element and its indicator */
ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
...
@@ -298,6 +293,7 @@ dump_variables(struct arguments * list)
...
@@ -298,6 +293,7 @@ dump_variables(struct arguments * list)
(list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->type : NULL, NULL, NULL);
(list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->type : NULL, NULL, NULL);
/* Then release the list element. */
/* Then release the list element. */
if (mode != 0)
free(list);
free(list);
}
}
...
@@ -494,9 +490,9 @@ output_statement(char * stmt, int mode)
...
@@ -494,9 +490,9 @@ output_statement(char * stmt, int mode)
fputs("\", ", yyout);
fputs("\", ", yyout);
/* dump variables to C file*/
/* dump variables to C file*/
dump_variables(argsinsert);
dump_variables(argsinsert
, 1
);
fputs("ECPGt_EOIT, ", yyout);
fputs("ECPGt_EOIT, ", yyout);
dump_variables(argsresult);
dump_variables(argsresult
, 1
);
fputs("ECPGt_EORT);", yyout);
fputs("ECPGt_EORT);", yyout);
whenever_action(mode);
whenever_action(mode);
free(stmt);
free(stmt);
...
@@ -737,10 +733,9 @@ stmt: AddAttrStmt { output_statement($1, 0); }
...
@@ -737,10 +733,9 @@ stmt: AddAttrStmt { output_statement($1, 0); }
| RenameStmt { output_statement($1, 0); }
| RenameStmt { output_statement($1, 0); }
| RevokeStmt { output_statement($1, 0); }
| RevokeStmt { output_statement($1, 0); }
| OptimizableStmt {
| OptimizableStmt {
if (strncmp($1, "
ECPGdeclare" , sizeof("ECPGdeclare
")-1) == 0)
if (strncmp($1, "
/* " , sizeof("/*
")-1) == 0)
{
{
fputs($1, yyout);
fputs($1, yyout);
whenever_action(0);
free($1);
free($1);
}
}
else
else
...
@@ -775,7 +770,27 @@ stmt: AddAttrStmt { output_statement($1, 0); }
...
@@ -775,7 +770,27 @@ stmt: AddAttrStmt { output_statement($1, 0); }
whenever_action(0);
whenever_action(0);
free($1);
free($1);
}
}
| ECPGOpen { fprintf(yyout, "ECPGopen(__LINE__, %s);", $1);
| ECPGOpen {
struct cursor *ptr;
for (ptr = cur; ptr != NULL; ptr=ptr->next)
{
if (strcmp(ptr->name, $1) == 0)
break;
}
if (ptr == NULL)
{
sprintf(errortext, "trying to open undeclared cursor %s\n", $1);
yyerror(errortext);
}
fprintf(yyout, "ECPGdo(__LINE__, \"%s\",", ptr->command);
/* dump variables to C file*/
dump_variables(ptr->argsinsert, 0);
fputs("ECPGt_EOIT, ", yyout);
dump_variables(ptr->argsresult, 0);
fputs("ECPGt_EORT);", yyout);
whenever_action(0);
whenever_action(0);
free($1);
free($1);
}
}
...
@@ -2359,7 +2374,31 @@ CursorStmt: DECLARE name opt_binary CURSOR FOR
...
@@ -2359,7 +2374,31 @@ CursorStmt: DECLARE name opt_binary CURSOR FOR
group_clause having_clause
group_clause having_clause
union_clause sort_clause
union_clause sort_clause
{
{
$$ = make5_str(make1_str("ECPGdeclare(__LINE__, \""), $2, make1_str("\", \""), cat4_str(cat5_str(cat5_str(make1_str("declare"), strdup($2), $3, make1_str("cursor for select"), $7), $8, $9, $10, $11), $12, $13, $14), make1_str("\");"));
struct cursor *ptr, *this;
for (ptr = cur; ptr != NULL; ptr = ptr->next)
{
if (strcmp($2, ptr->name) == 0)
{
/* re-definition is a bug*/
sprintf(errortext, "cursor %s already defined", $2);
yyerror(errortext);
}
}
this = (struct cursor *) mm_alloc(sizeof(struct cursor));
/* initial definition */
this->next = cur;
this->name = $2;
this->command = cat4_str(cat5_str(cat5_str(make1_str("declare"), strdup($2), $3, make1_str("cursor for select"), $7), $8, $9, $10, $11), $12, $13, $14);
this->argsinsert = argsinsert;
this->argsresult = argsresult;
argsinsert = argsresult = NULL;
cur = this;
$$ = cat3_str(make1_str("/*"), strdup(this->command), make1_str("*/"));
}
}
;
;
...
@@ -4221,7 +4260,7 @@ execstring: cvariable |
...
@@ -4221,7 +4260,7 @@ execstring: cvariable |
* open is an open cursor, at the moment this has to be removed
* open is an open cursor, at the moment this has to be removed
*/
*/
ECPGOpen: SQL_OPEN name open_opts {
ECPGOpen: SQL_OPEN name open_opts {
$$ =
make3_str(make1_str("\""), $2, make1_str("\""))
;
$$ =
$2
;
};
};
open_opts: /* empty */ { $$ = make1_str(""); }
open_opts: /* empty */ { $$ = make1_str(""); }
...
...
src/interfaces/ecpg/test/Makefile
View file @
c6dd1e63
all
:
test1 test2 perftest
all
:
test1 test2 perftest
LDFLAGS
=
-g
-I
../include
-I
../../libpq
-L
../lib
-lecpg
-L
../../libpq
-lpq
-lcrypt
--static
LDFLAGS
=
-g
-I
../include
-I
../../libpq
-L
../lib
-lecpg
-L
../../libpq
-lpq
-lcrypt
test1
:
test1.c
test1
:
test1.c
test1.c
:
test1.pgc
test1.c
:
test1.pgc
...
...
src/interfaces/ecpg/test/test2.pgc
View file @
c6dd1e63
...
@@ -19,6 +19,10 @@ exec sql begin declare section;
...
@@ -19,6 +19,10 @@ exec sql begin declare section;
long ind_married;
long ind_married;
char married[9];
char married[9];
exec sql end declare section;
exec sql end declare section;
exec sql declare cur cursor for
select name, born, age, married from meskes;
char msg[128], command[128];
char msg[128], command[128];
FILE *dbgs;
FILE *dbgs;
...
@@ -41,10 +45,6 @@ exec sql end declare section;
...
@@ -41,10 +45,6 @@ exec sql end declare section;
strcpy(msg, "commit");
strcpy(msg, "commit");
exec sql commit;
exec sql commit;
strcpy(msg, "declare");
exec sql declare cur cursor for
select name, born, age, married from meskes;
strcpy(msg, "open");
strcpy(msg, "open");
exec sql open cur;
exec sql open cur;
...
...
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