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
8cb8da38
Commit
8cb8da38
authored
Mar 01, 2000
by
Michael Meskes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
parent
a50aaa72
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
278 additions
and
190 deletions
+278
-190
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/ChangeLog
+5
-0
src/interfaces/ecpg/TODO
src/interfaces/ecpg/TODO
+0
-5
src/interfaces/ecpg/include/ecpgerrno.h
src/interfaces/ecpg/include/ecpgerrno.h
+23
-21
src/interfaces/ecpg/include/ecpglib.h
src/interfaces/ecpg/include/ecpglib.h
+2
-2
src/interfaces/ecpg/include/sql3types.h
src/interfaces/ecpg/include/sql3types.h
+1
-1
src/interfaces/ecpg/lib/data.c
src/interfaces/ecpg/lib/data.c
+42
-8
src/interfaces/ecpg/lib/descriptor.c
src/interfaces/ecpg/lib/descriptor.c
+1
-24
src/interfaces/ecpg/lib/ecpglib.c
src/interfaces/ecpg/lib/ecpglib.c
+36
-16
src/interfaces/ecpg/lib/error.c
src/interfaces/ecpg/lib/error.c
+10
-0
src/interfaces/ecpg/lib/typename.c
src/interfaces/ecpg/lib/typename.c
+25
-0
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/preproc.y
+133
-113
No files found.
src/interfaces/ecpg/ChangeLog
View file @
8cb8da38
...
...
@@ -832,5 +832,10 @@ Wed Feb 23 17:08:28 CET 2000
Fri Feb 25 16:13:11 CET 2000
- Fixed some bugs I created when I cleaned up, thanks Christof.
Wed Mar 1 10:49:03 CET 2000
- Synced preproc.y with gram.y.
- Added output of arrays.
- Set library version to 3.1.0.
- Set ecpg version to 2.7.0.
src/interfaces/ecpg/TODO
View file @
8cb8da38
...
...
@@ -16,8 +16,6 @@ the parser.
it would be nice to be able to use :var[:index] or :var[<integer>] as
cvariable for an array var
How can one insert arrays from c variables?
What happens to the output variable during read if there was an
indicator-error?
...
...
@@ -26,10 +24,7 @@ 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.
make ECPGnumeric_lvalue more accurate by using something like ECPGdump_a_*
remove space_or_nl and line_end from pgc.l
Missing statements:
- exec sql ifdef
- SQLSTATE
src/interfaces/ecpg/include/ecpgerrno.h
View file @
8cb8da38
...
...
@@ -13,32 +13,34 @@
#define ECPG_OUT_OF_MEMORY -ENOMEM
/* first we have a set of ecpg messages, they start at 200 */
#define ECPG_UNSUPPORTED -200
#define ECPG_TOO_MANY_ARGUMENTS -201
#define ECPG_TOO_FEW_ARGUMENTS -202
#define ECPG_TOO_MANY_MATCHES -203
#define ECPG_INT_FORMAT -204
#define ECPG_UINT_FORMAT -205
#define ECPG_FLOAT_FORMAT -206
#define ECPG_CONVERT_BOOL -207
#define ECPG_EMPTY -208
#define ECPG_MISSING_INDICATOR -209
#define ECPG_NO_CONN -220
#define ECPG_NOT_CONN -221
#define ECPG_INVALID_STMT -230
#define ECPG_UNSUPPORTED -200
#define ECPG_TOO_MANY_ARGUMENTS -201
#define ECPG_TOO_FEW_ARGUMENTS -202
#define ECPG_TOO_MANY_MATCHES -203
#define ECPG_INT_FORMAT -204
#define ECPG_UINT_FORMAT -205
#define ECPG_FLOAT_FORMAT -206
#define ECPG_CONVERT_BOOL -207
#define ECPG_EMPTY -208
#define ECPG_MISSING_INDICATOR -209
#define ECPG_NO_ARRAY -210
#define ECPG_DATA_NOT_ARRAY -211
#define ECPG_NO_CONN -220
#define ECPG_NOT_CONN -221
#define ECPG_INVALID_STMT -230
/* dynamic SQL related */
#define ECPG_UNKNOWN_DESCRIPTOR -240
#define ECPG_UNKNOWN_DESCRIPTOR
-240
#define ECPG_INVALID_DESCRIPTOR_INDEX -241
#define ECPG_UNKNOWN_DESCRIPTOR_ITEM -242
#define ECPG_VAR_NOT_NUMERIC -243
#define ECPG_VAR_NOT_CHAR -244
#define ECPG_VAR_NOT_NUMERIC
-243
#define ECPG_VAR_NOT_CHAR
-244
/* finally the backend error messages, they start at 400 */
#define ECPG_PGSQL -400
#define ECPG_TRANS -401
#define ECPG_CONNECT -402
#define ECPG_PGSQL
-400
#define ECPG_TRANS
-401
#define ECPG_CONNECT
-402
#endif
/* !_ECPG_ERROR_H */
src/interfaces/ecpg/include/ecpglib.h
View file @
8cb8da38
...
...
@@ -30,12 +30,12 @@ extern "C"
/* Here are some methods used by the lib. */
/* Returns a pointer to a string containing a simple type name. */
const
char
*
ECPGtype_name
(
enum
ECPGttype
);
bool
get_data
(
PGresult
*
,
int
,
int
,
int
,
enum
ECPGttype
type
,
enum
ECPGttype
,
void
*
,
void
*
,
long
,
long
);
enum
ECPGttype
,
void
*
,
void
*
,
long
,
long
,
bool
);
char
*
ecpg_alloc
(
long
,
int
);
char
*
ecpg_strdup
(
const
char
*
,
int
);
const
char
*
ECPGtype_name
(
enum
ECPGttype
);
unsigned
int
ECPGDynamicType
(
Oid
);
/* and some vars */
extern
struct
auto_mem
*
auto_allocs
;
...
...
src/interfaces/ecpg/include/sql3types.h
View file @
8cb8da38
...
...
@@ -2,7 +2,7 @@
*
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
*
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/include/sql3types.h,v 1.
1 2000/02/16 16:18:03
meskes Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/include/sql3types.h,v 1.
2 2000/03/01 12:49:41
meskes Exp $
*/
/* chapter 13.1 table 2: Codes used for SQL data types in Dynamic SQL */
...
...
src/interfaces/ecpg/lib/data.c
View file @
8cb8da38
...
...
@@ -8,13 +8,26 @@
bool
get_data
(
PGresult
*
results
,
int
act_tuple
,
int
act_field
,
int
lineno
,
enum
ECPGttype
type
,
enum
ECPGttype
ind_type
,
void
*
var
,
void
*
ind
,
long
varcharsize
,
long
offset
)
void
*
var
,
void
*
ind
,
long
varcharsize
,
long
offset
,
bool
isarray
)
{
char
*
pval
=
(
char
*
)
PQgetvalue
(
results
,
act_tuple
,
act_field
);
ECPGlog
(
"get_data line %d: RESULT: %s
\n
"
,
lineno
,
pval
?
pval
:
""
);
/* Now the pval is a pointer to the value. */
/* let's check is it really is an array if it should be */
if
(
isarray
)
{
if
(
*
pval
!=
'{'
)
{
ECPGlog
(
"get_data data entry does not look like an array in line %d
\n
"
,
lineno
);
ECPGraise
(
lineno
,
ECPG_DATA_NOT_ARRAY
,
NULL
);
return
(
false
);
}
else
++
pval
;
}
/* We will have to decode the value */
/*
...
...
@@ -48,8 +61,10 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
break
;
}
switch
(
type
)
{
do
{
switch
(
type
)
{
long
res
;
unsigned
long
ures
;
double
dres
;
...
...
@@ -61,7 +76,8 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
if
(
pval
)
{
res
=
strtol
(
pval
,
&
scan_length
,
10
);
if
(
*
scan_length
!=
'\0'
)
/* Garbage left */
if
((
isarray
&&
*
scan_length
!=
','
&&
*
scan_length
!=
'}'
)
||
(
!
isarray
&&
*
scan_length
!=
'\0'
))
/* Garbage left */
{
ECPGraise
(
lineno
,
ECPG_INT_FORMAT
,
pval
);
return
(
false
);
...
...
@@ -94,7 +110,8 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
if
(
pval
)
{
ures
=
strtoul
(
pval
,
&
scan_length
,
10
);
if
(
*
scan_length
!=
'\0'
)
/* Garbage left */
if
((
isarray
&&
*
scan_length
!=
','
&&
*
scan_length
!=
'}'
)
||
(
!
isarray
&&
*
scan_length
!=
'\0'
))
/* Garbage left */
{
ECPGraise
(
lineno
,
ECPG_UINT_FORMAT
,
pval
);
return
(
false
);
...
...
@@ -127,7 +144,8 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
if
(
pval
)
{
dres
=
strtod
(
pval
,
&
scan_length
);
if
(
*
scan_length
!=
'\0'
)
/* Garbage left */
if
((
isarray
&&
*
scan_length
!=
','
&&
*
scan_length
!=
'}'
)
||
(
!
isarray
&&
*
scan_length
!=
'\0'
))
/* Garbage left */
{
ECPGraise
(
lineno
,
ECPG_FLOAT_FORMAT
,
pval
);
return
(
false
);
...
...
@@ -246,7 +264,23 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
ECPGraise
(
lineno
,
ECPG_UNSUPPORTED
,
ECPGtype_name
(
type
));
return
(
false
);
break
;
}
}
if
(
isarray
)
{
bool
string
=
false
;
/* set array to next entry */
++
act_tuple
;
/* set pval to the next entry */
for
(;
string
||
(
*
pval
!=
','
&&
*
pval
!=
'}'
);
++
pval
)
if
(
*
pval
==
'"'
)
string
=
string
?
false
:
true
;
if
(
*
pval
==
','
)
++
pval
;
}
}
while
(
isarray
&&
*
pval
!=
'}'
);
return
(
true
);
}
src/interfaces/ecpg/lib/descriptor.c
View file @
8cb8da38
...
...
@@ -25,28 +25,6 @@ static PGresult
return
NULL
;
}
static
unsigned
int
ECPGDynamicType
(
Oid
type
)
{
switch
(
type
)
{
case
16
:
return
SQL3_BOOLEAN
;
/* bool */
case
21
:
return
SQL3_SMALLINT
;
/* int2 */
case
23
:
return
SQL3_INTEGER
;
/* int4 */
case
25
:
return
SQL3_CHARACTER
;
/* text */
case
700
:
return
SQL3_REAL
;
/* float4 */
case
701
:
return
SQL3_DOUBLE_PRECISION
;
/* float8 */
case
1042
:
return
SQL3_CHARACTER
;
/* bpchar */
case
1043
:
return
SQL3_CHARACTER_VARYING
;
/* varchar */
case
1082
:
return
SQL3_DATE_TIME_TIMESTAMP
;
/* date */
case
1083
:
return
SQL3_DATE_TIME_TIMESTAMP
;
/* time */
case
1184
:
return
SQL3_DATE_TIME_TIMESTAMP
;
/* datetime */
case
1296
:
return
SQL3_DATE_TIME_TIMESTAMP
;
/* timestamp */
case
1700
:
return
SQL3_NUMERIC
;
/* numeric */
default:
return
-
type
;
}
}
static
unsigned
int
ECPGDynamicType_DDT
(
Oid
type
)
{
...
...
@@ -61,7 +39,6 @@ ECPGDynamicType_DDT(Oid type)
}
}
bool
ECPGget_desc_header
(
int
lineno
,
char
*
desc_name
,
int
*
count
)
{
...
...
@@ -266,7 +243,7 @@ ECPGget_desc(int lineno, char *desc_name, int index, ...)
ECPGlog
(
"ECPGget_desc: TYPE = %d
\n
"
,
ECPGDynamicType_DDT
(
PQftype
(
ECPGresult
,
index
)));
break
;
case
ECPGd_data
:
if
(
!
get_data
(
ECPGresult
,
0
,
index
,
lineno
,
vartype
,
ECPGt_NO_INDICATOR
,
var
,
NULL
,
varcharsize
,
offset
))
if
(
!
get_data
(
ECPGresult
,
0
,
index
,
lineno
,
vartype
,
ECPGt_NO_INDICATOR
,
var
,
NULL
,
varcharsize
,
offset
,
false
))
return
(
false
);
break
;
...
...
src/interfaces/ecpg/lib/ecpglib.c
View file @
8cb8da38
...
...
@@ -24,6 +24,7 @@
#include <ecpgtype.h>
#include <ecpglib.h>
#include <sqlca.h>
#include <sql3types.h>
/* variables visible to the programs */
static
struct
sqlca
sqlca_init
=
...
...
@@ -689,23 +690,46 @@ ECPGexecute(struct statement * stmt)
isarray
=
0
;
if
(
PQresultStatus
(
query
)
==
PGRES_TUPLES_OK
)
{
isarray
=
atol
((
char
*
)
PQgetvalue
(
query
,
0
,
0
));
if
(
ECPGDynamicType
(
PQftype
(
results
,
act_field
))
==
SQL3_CHARACTER
||
(
PQftype
(
results
,
act_field
))
==
SQL3_CHARACTER_VARYING
)
{
/* arrays of character strings are not yet implemented */
isarray
=
false
;
}
ECPGlog
(
"ECPGexecute line %d: TYPE database: %d C: %d array: %s
\n
"
,
stmt
->
lineno
,
PQftype
(
results
,
act_field
),
var
->
type
,
isarray
?
"yes"
:
"no"
);
}
PQclear
(
query
);
/*
* if we don't have enough space, we cannot read all
* tuples
*/
if
((
var
->
arrsize
>
0
&&
ntuples
>
var
->
arrsize
)
||
(
var
->
ind_arrsize
>
0
&&
ntuples
>
var
->
ind_arrsize
))
if
(
!
isarray
)
{
ECPGlog
(
"ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d
\n
"
,
/*
* if we don't have enough space, we cannot read all
* tuples
*/
if
((
var
->
arrsize
>
0
&&
ntuples
>
var
->
arrsize
)
||
(
var
->
ind_arrsize
>
0
&&
ntuples
>
var
->
ind_arrsize
))
{
ECPGlog
(
"ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d
\n
"
,
stmt
->
lineno
,
ntuples
,
var
->
arrsize
);
ECPGraise
(
stmt
->
lineno
,
ECPG_TOO_MANY_MATCHES
,
NULL
);
status
=
false
;
break
;
ECPGraise
(
stmt
->
lineno
,
ECPG_TOO_MANY_MATCHES
,
NULL
);
status
=
false
;
break
;
}
}
else
{
/*
* since we read an array, the variable has to be
* an array too
*/
if
(
var
->
arrsize
==
0
)
{
ECPGlog
(
"ECPGexecute line %d: variable is not an array
\n
"
);
ECPGraise
(
stmt
->
lineno
,
ECPG_NO_ARRAY
,
NULL
);
status
=
false
;
break
;
}
}
/*
* allocate memory for NULL pointers
*/
...
...
@@ -745,7 +769,7 @@ ECPGexecute(struct statement * stmt)
{
if
(
!
get_data
(
results
,
act_tuple
,
act_field
,
stmt
->
lineno
,
var
->
type
,
var
->
ind_type
,
var
->
value
,
var
->
ind_value
,
var
->
varcharsize
,
var
->
offset
))
var
->
ind_value
,
var
->
varcharsize
,
var
->
offset
,
isarray
))
status
=
false
;
}
var
=
var
->
next
;
...
...
@@ -1067,13 +1091,9 @@ ECPGlog(const char *format,...)
*
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
*
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/ecpglib.c,v 1.6
0 2000/02/23 19:25:43
meskes Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/ecpglib.c,v 1.6
1 2000/03/01 12:49:42
meskes Exp $
*/
/* I borrowed the include files from ecpglib.c, maybe we don't need all of them */
#include <sql3types.h>
PGconn
*
ECPG_internal_get_connection
(
char
*
name
);
extern
struct
descriptor
...
...
src/interfaces/ecpg/lib/error.c
View file @
8cb8da38
...
...
@@ -67,6 +67,16 @@ ECPGraise(int line, int code, const char *str)
snprintf
(
sqlca
.
sqlerrm
.
sqlerrmc
,
sizeof
(
sqlca
.
sqlerrm
.
sqlerrmc
),
"NULL value without indicator in line %d."
,
line
);
break
;
case
ECPG_NO_ARRAY
:
snprintf
(
sqlca
.
sqlerrm
.
sqlerrmc
,
sizeof
(
sqlca
.
sqlerrm
.
sqlerrmc
),
"variable is not an array in line %d."
,
line
);
break
;
case
ECPG_DATA_NOT_ARRAY
:
snprintf
(
sqlca
.
sqlerrm
.
sqlerrmc
,
sizeof
(
sqlca
.
sqlerrm
.
sqlerrmc
),
"data read from backend is not an array in line %d."
,
line
);
break
;
case
ECPG_NO_CONN
:
snprintf
(
sqlca
.
sqlerrm
.
sqlerrmc
,
sizeof
(
sqlca
.
sqlerrm
.
sqlerrmc
),
...
...
src/interfaces/ecpg/lib/typename.c
View file @
8cb8da38
#include <stdlib.h>
#include <ecpgtype.h>
#include <ecpglib.h>
#include <sql3types.h>
/*
* This function is used to generate the correct type names.
*/
...
...
@@ -39,3 +42,25 @@ ECPGtype_name(enum ECPGttype typ)
}
return
NULL
;
}
unsigned
int
ECPGDynamicType
(
Oid
type
)
{
switch
(
type
)
{
case
16
:
return
SQL3_BOOLEAN
;
/* bool */
case
21
:
return
SQL3_SMALLINT
;
/* int2 */
case
23
:
return
SQL3_INTEGER
;
/* int4 */
case
25
:
return
SQL3_CHARACTER
;
/* text */
case
700
:
return
SQL3_REAL
;
/* float4 */
case
701
:
return
SQL3_DOUBLE_PRECISION
;
/* float8 */
case
1042
:
return
SQL3_CHARACTER
;
/* bpchar */
case
1043
:
return
SQL3_CHARACTER_VARYING
;
/* varchar */
case
1082
:
return
SQL3_DATE_TIME_TIMESTAMP
;
/* date */
case
1083
:
return
SQL3_DATE_TIME_TIMESTAMP
;
/* time */
case
1184
:
return
SQL3_DATE_TIME_TIMESTAMP
;
/* datetime */
case
1296
:
return
SQL3_DATE_TIME_TIMESTAMP
;
/* timestamp */
case
1700
:
return
SQL3_NUMERIC
;
/* numeric */
default:
return
-
type
;
}
}
src/interfaces/ecpg/preproc/preproc.y
View file @
8cb8da38
...
...
@@ -275,7 +275,7 @@ make_name(void)
%type <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId
%type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt
%type <str> OptInherit key_reference comment_text
%type <str> OptInherit key_reference comment_text
ConstraintDeferrabilitySpec
%type <str> key_match ColLabel SpecialRuleRelation ColId columnDef
%type <str> ColConstraint ColConstraintElem NumericOnly FloatOnly
%type <str> OptTableElementList OptTableElement TableConstraint
...
...
@@ -283,7 +283,7 @@ make_name(void)
%type <str> target_list target_el update_target_list alias_clause
%type <str> update_target_el opt_id relation_name database_name
%type <str> access_method attr_name class index_name name func_name
%type <str> file_name AexprConst ParamNo TypeId c_expr
ColQualListWithNull
%type <str> file_name AexprConst ParamNo TypeId c_expr
%type <str> in_expr_nodes a_expr b_expr TruncateStmt CommentStmt
%type <str> opt_indirection expr_list extract_list extract_arg
%type <str> position_list substr_list substr_from alter_column_action
...
...
@@ -292,8 +292,8 @@ make_name(void)
%type <str> opt_decimal Character character opt_varying opt_charset
%type <str> opt_collate Datetime datetime opt_timezone opt_interval
%type <str> numeric a_expr_or_null row_expr row_descriptor row_list
%type <str> SelectStmt SubSelect result OptTemp
OptTempType OptTempScope
%type <str> opt_table opt_all sort_clause sortby_list Co
lQualifier
%type <str> SelectStmt SubSelect result OptTemp
ConstraintAttributeSpec
%type <str> opt_table opt_all sort_clause sortby_list Co
nstraintAttr
%type <str> sortby OptUseOp opt_inh_star relation_name_list name_list
%type <str> group_clause having_clause from_clause opt_distinct
%type <str> join_outer where_clause relation_expr sub_type
...
...
@@ -329,18 +329,16 @@ make_name(void)
%type <str> GrantStmt privileges operation_commalist operation
%type <str> opt_cursor opt_lmode ConstraintsSetStmt comment_tg
%type <str> case_expr when_clause_list case_default case_arg when_clause
%type <str> select_clause opt_select_limit select_limit_value
TimeClause
%type <str> select_clause opt_select_limit select_limit_value
ConstraintTimeSpec
%type <str> select_offset_value using_expr join_expr ReindexStmt
%type <str> using_list from_expr join_clause join_type
%type <str> join_qual update_list join_clause join_clause_with_union
%type <str> opt_level opt_lock lock_type users_in_new_group_clause
%type <str> OptConstrFromTable comment_op
ConstraintAttribut
e
%type <str> OptConstrFromTable comment_op
OptTempTableNam
e
%type <str> constraints_set_list constraints_set_namelist comment_fn
%type <str> constraints_set_mode comment_type comment_cl comment_ag
%type <str> CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
%type <str> ColConstraintWithNull ColConstraintElemWithNull NotNull
%type <str> join_expr_with_union DefaultClause DefaultExpr PrimaryKey
%type <str> DeferrabilityClause opt_force key_update
%type <str> join_expr_with_union opt_force key_update
/***
#ifdef ENABLE_ORACLE_JOIN_SYNTAX
%type <str> oracle_list oracle_expr oracle_outer
...
...
@@ -991,24 +989,26 @@ CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
}
;
OptTemp: OptTempType { $$ = $1; }
| OptTempScope OptTempType { $$ = cat2_str($1,$2); }
;
/*
* Redundancy here is needed to avoid shift/reduce conflicts,
* since TEMP is not a reserved word. See also OptTempTableName.
*/
OptTempType: TEMP { $$ = make_str("temp"); }
| TEMPORARY { $$ = make_str("temporary"); }
| /* EMPTY */ { $$ = EMPTY; }
OptTemp: TEMPORARY { $$ = make_str("temporary"); }
| TEMP { $$ = make_str("temp"); }
| LOCAL TEMPORARY { $$ = make_str("local temporary"); }
| LOCAL TEMP { $$ = make_str("local temp"); }
| GLOBAL TEMPORARY {
mmerror(ET_ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
$$ = make_str("global temporary");
}
| GLOBAL TEMP {
mmerror(ET_ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
$$ = make_str("global temp");
}
| /*EMPTY*/ { $$ = EMPTY; }
;
OptTempScope: GLOBAL
{
mmerror(ET_ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
$$ = make_str("global");
}
| LOCAL { $$ = make_str("local"); }
;
OptTableElementList: OptTableElementList ',' OptTableElement
{
$$ = cat_str(3, $1, make_str(","), $3);
...
...
@@ -1024,7 +1024,7 @@ OptTableElement: columnDef { $$ = $1; }
| TableConstraint { $$ = $1; }
;
columnDef: ColId Typename ColQual
ifier
opt_collate
columnDef: ColId Typename ColQual
List
opt_collate
{
if (strlen($4) > 0)
{
...
...
@@ -1033,7 +1033,7 @@ columnDef: ColId Typename ColQualifier opt_collate
}
$$ = cat_str(4, $1, $2, $3, $4);
}
| ColId SERIAL ColQual
ifier
opt_collate
| ColId SERIAL ColQual
List
opt_collate
{
if (strlen($4) > 0)
{
...
...
@@ -1044,55 +1044,18 @@ columnDef: ColId Typename ColQualifier opt_collate
}
;
/*
* ColQualifier encapsulates an entire column qualification,
* including DEFAULT, constraints, and constraint attributes.
* Note that the DefaultClause handles the empty case.
*/
ColQualifier: DefaultClause ColQualList { $$ = cat2_str($1, $2); }
| NotNull DefaultClause ColQualListWithNull { $$ = cat_str(3, $1, $2, $3); }
| DefaultExpr NotNull ColQualListWithNull { $$ = cat_str(3, $1, $2, $3); }
| DefaultExpr NotNull { $$ = cat2_str($1, $2); }
| NotNull DefaultClause { $$ = cat2_str($1, $2); }
| NULL_P DefaultClause ColQualListWithNull { $$ = cat_str(3, make_str("null"), $2, $3); }
| NULL_P DefaultClause { $$ = cat2_str(make_str("null"), $2); }
| DefaultClause { $$ = $1; }
;
/*
* DEFAULT expression must be b_expr not a_expr to prevent shift/reduce
* conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
* or be part of a_expr NOT LIKE or similar constructs).
*/
DefaultClause: DefaultExpr { $$ = $1; }
| /*EMPTY*/ { $$ = EMPTY; }
;
DefaultExpr: DEFAULT NULL_P { $$ = make_str("default null"); }
| DEFAULT b_expr { $$ = cat2_str(make_str("default"), $2); }
;
ColQualList: ColQualList ColConstraint { $$ = cat2_str($1,$2); }
|
ColConstraint { $$ = $1
; }
|
/*EMPTY*/ { $$ = EMPTY
; }
;
ColQualListWithNull: ColConstraintWithNull ColQualListWithNull
{ $$ = cat2_str($1, $2); }
| ColConstraintWithNull
{ $$ = $1; }
ColConstraint: CONSTRAINT name ColConstraintElem
{
$$ = cat_str(3, make_str("constraint"), $2, $3);
}
| ColConstraintElem
{ $$ = $1; }
;
ColConstraintWithNull: CONSTRAINT name ColConstraintElemWithNull
{ $$ = cat_str(3, make_str("constraint"), $2, $3); }
| ColConstraintElemWithNull
{ $$ = $1; }
| ConstraintAttr
{ $$ = $1; }
;
/* DEFAULT NULL is already the default for Postgres.
...
...
@@ -1106,40 +1069,56 @@ ColConstraintWithNull: CONSTRAINT name ColConstraintElemWithNull
* shift/reduce conflicts with WITH TIME ZONE anyway.
* - thomas 1999-01-08
*/
ColConstraintElem: ColConstraintElemWithNull
{
$$ = $1;
}
| UNIQUE
ColConstraintElem: NOT NULL_P
{
$$ = make_str("not null");
}
| NULL_P
{
$$ = make_str("null");
}
| UNIQUE
{
$$ = make_str("unique");
}
| P
rimaryKey
| P
RIMARY KEY
{
$$ =
$1
;
$$ =
make_str("primary key")
;
}
;
ColConstraintElemWithNull: CHECK '(' a_expr ')'
| CHECK '(' a_expr ')'
{
$$ = cat_str(3, make_str("check("), $3, make_str(")"));
$$ = cat_str(3, make_str("check
("), $3, make_str(")"));
}
| REFERENCES ColId opt_column_list
key_match key_actions ConstraintAttribute
| DEFAULT NULL_P
{
$$ =
cat_str(6, make_str("references"), $2, $3, $4, $5, $6
);
$$ =
make_str("default null"
);
}
| REFERENCES ColId opt_column_list
key_match key_actions
| DEFAULT b_expr
{
$$ = cat
_str(5, make_str("references"), $2, $3, $4, $5
);
$$ = cat
2_str(make_str("default"), $2
);
}
;
PrimaryKey: PRIMARY KEY { $$ = make_str("primary key"); }
| REFERENCES ColId opt_column_list key_match key_actions
{
$$ = cat_str(5, make_str("references"), $2, $3, $4, $5);
}
;
NotNull: NOT NULL_P { $$ = make_str("not null"); }
/*
* ConstraintAttr represents constraint attributes, which we parse as if
* they were independent constraint clauses, in order to avoid shift/reduce
* conflicts (since NOT might start either an independent NOT NULL clause
* or an attribute). analyze.c is responsible for attaching the attribute
* information to the preceding "real" constraint node, and for complaining
* if attribute clauses appear in the wrong place or wrong combinations.
*
* See also ConstraintAttributeSpec, which can be used in places where
* there is no parsing conflict.
*/
ConstraintAttr: DEFERRABLE { $$ = make_str("deferrable"); }
| NOT DEFERRABLE { $$ = make_str("not deferrable"); }
| INITIALLY DEFERRED { $$ = make_str("initially deferred"); }
| INITIALLY IMMEDIATE { $$ = make_str("initially immediate"); }
;
/* ConstraintElem specifies constraint syntax which is not embedded into
* a column definition. ColConstraintElem specifies the embedded form.
...
...
@@ -1161,20 +1140,15 @@ ConstraintElem: CHECK '(' a_expr ')'
{
$$ = cat_str(3, make_str("unique("), $3, make_str(")"));
}
| P
rimaryKey
'(' columnList ')'
| P
RIMARY KEY
'(' columnList ')'
{
$$ = cat_str(3, make_str("primary key("), $
3
, make_str(")"));
$$ = cat_str(3, make_str("primary key("), $
4
, make_str(")"));
}
| FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list
key_match key_actions ConstraintAttribute
key_match key_actions ConstraintAttribute
Spec
{
$$ = cat_str(8, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10, $11);
}
| FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list
key_match key_actions
{
$$ = cat_str(7, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10);
}
;
key_match: MATCH FULL
...
...
@@ -1347,7 +1321,7 @@ CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
}
| CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
relation_name OptConstrFromTable
ConstraintAttribute
ConstraintAttribute
Spec
FOR EACH ROW EXECUTE PROCEDURE
name '(' TriggerFuncArgs ')'
{
...
...
@@ -1422,18 +1396,18 @@ OptConstrFromTable: /* Empty */
}
;
ConstraintAttribute
: DeferrabilityClause
ConstraintAttribute
Spec: ConstraintDeferrabilitySpec
{ $$ = $1; }
| TimeClause
{ $$ = $1; }
| DeferrabilityClause TimeClause
{
| ConstraintDeferrabilitySpec ConstraintTimeSpec
{
if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 )
mmerror(ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
$$ = cat2_str($1, $2);
$$ = cat2_str($1, $2);
}
| TimeClause DeferrabilityClause
| ConstraintTimeSpec
{ $$ = $1; }
| ConstraintTimeSpec ConstraintDeferrabilitySpec
{
if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
mmerror(ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
...
...
@@ -1442,11 +1416,11 @@ ConstraintAttribute: DeferrabilityClause
}
;
DeferrabilityClause
: NOT DEFERRABLE { $$ = make_str("not deferrable"); }
ConstraintDeferrabilitySpec
: NOT DEFERRABLE { $$ = make_str("not deferrable"); }
| DEFERRABLE { $$ = make_str("deferrable"); }
;
TimeClause
: INITIALLY IMMEDIATE { $$ = make_str("initially immediate"); }
ConstraintTimeSpec
: INITIALLY IMMEDIATE { $$ = make_str("initially immediate"); }
| INITIALLY DEFERRED { $$ = make_str("initially deferrable"); }
;
...
...
@@ -2545,13 +2519,57 @@ SubSelect: SELECT opt_distinct target_list
}
;
result: INTO OptTemp opt_table relation_name { FoundInto = 1;
$$= cat_str(4, make_str("into"), $2, $3, $4);
}
| INTO into_list { $$ = EMPTY; }
| /*EMPTY*/ { $$ = EMPTY; }
result: INTO OptTempTableName {
FoundInto = 1;
$$= cat2_str(make_str("into"), $2);
}
| INTO into_list { $$ = EMPTY; }
| /*EMPTY*/ { $$ = EMPTY; }
;
/*
* Redundancy here is needed to avoid shift/reduce conflicts,
* since TEMP is not a reserved word. See also OptTemp.
*
* The result is a cons cell (not a true list!) containing
* a boolean and a table name.
*/
OptTempTableName: TEMPORARY opt_table relation_name
{
$$ = cat_str(3, make_str("temporary"), $2, $3);
}
| TEMP opt_table relation_name
{
$$ = cat_str(3, make_str("temp"), $2, $3);
}
| LOCAL TEMPORARY opt_table relation_name
{
$$ = cat_str(3, make_str("local temporary"), $3, $4);
}
| LOCAL TEMP opt_table relation_name
{
$$ = cat_str(3, make_str("local temp"), $3, $4);
}
| GLOBAL TEMPORARY opt_table relation_name
{
mmerror(ET_ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
$$ = cat_str(3, make_str("global temporary"), $3, $4);
}
| GLOBAL TEMP opt_table relation_name
{
mmerror(ET_ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
$$ = cat_str(3, make_str("global temp"), $3, $4);
}
| TABLE relation_name
{
$$ = cat2_str(make_str("table"), $2);
}
| relation_name
{
$$ = $1;
}
;
opt_table: TABLE { $$ = make_str("table"); }
| /*EMPTY*/ { $$ = EMPTY; }
;
...
...
@@ -3839,7 +3857,6 @@ ColId: ident { $$ = $1; }
| CREATEUSER { $$ = make_str("createuser"); }
| CYCLE { $$ = make_str("cycle"); }
| DATABASE { $$ = make_str("database"); }
| DEFERRABLE { $$ = make_str("deferrable"); }
| DEFERRED { $$ = make_str("deferred"); }
| DELIMITERS { $$ = make_str("delimiters"); }
| DOUBLE { $$ = make_str("double"); }
...
...
@@ -3853,7 +3870,6 @@ ColId: ident { $$ = $1; }
| INCREMENT { $$ = make_str("increment"); }
| INDEX { $$ = make_str("index"); }
| INHERITS { $$ = make_str("inherits"); }
| INITIALLY { $$ = make_str("initially"); }
| INSENSITIVE { $$ = make_str("insensitive"); }
| INSTEAD { $$ = make_str("instead"); }
| INTERVAL { $$ = make_str("interval"); }
...
...
@@ -3900,6 +3916,8 @@ ColId: ident { $$ = $1; }
| STDIN { $$ = make_str("stdin"); }
| STDOUT { $$ = make_str("stdout"); }
| SYSID { $$ = make_str("sysid"); }
| TEMP { $$ = make_str("temp"); }
| TEMPORARY { $$ = make_str("temporary"); }
| TIME { $$ = make_str("time"); }
| TIMESTAMP { $$ = make_str("timestamp"); }
| TIMEZONE_HOUR { $$ = make_str("timezone_hour"); }
...
...
@@ -3977,6 +3995,7 @@ ColLabel: ColId { $$ = $1; }
| CURRENT_USER { $$ = make_str("current_user"); }
| DEC { $$ = make_str("dec"); }
| DECIMAL { $$ = make_str("decimal"); }
| DEFERRABLE { $$ = make_str("deferrable"); }
| DO { $$ = make_str("do"); }
| ELSE { $$ = make_str("else"); }
| END_TRANS { $$ = make_str("end"); }
...
...
@@ -3987,6 +4006,7 @@ ColLabel: ColId { $$ = $1; }
| FOREIGN { $$ = make_str("foreign"); }
| GLOBAL { $$ = make_str("global"); }
| GROUP { $$ = make_str("group"); }
| INITIALLY { $$ = make_str("initially"); }
| LISTEN { $$ = make_str("listen"); }
| LOAD { $$ = make_str("load"); }
| LOCK_P { $$ = make_str("lock"); }
...
...
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