mirror of https://github.com/postgres/postgres
Implement SQL99 CREATE CAST and DROP CAST statements.
Also implement alternative forms to expose the PostgreSQL CREATE FUNCTION features. Implement syntax for READ ONLY and READ WRITE clauses in SET TRANSACTION. READ WRITE is already implemented (of course). Implement syntax for "LIKE table" clause in CREATE TABLE. Should be fairly easy to complete since it resembles SELECT INTO. Implement MATCH SIMPLE clause for foreign key definitions. This is explicit SQL99 syntax for the default behavior, so we now support it :) Start implementation of shorthand for national character literals in scanner. For now, just swallow the leading "N", but sometime soon let's figure out how to pass leading type info from the scanner to the parser. We should use the same technique for binary and hex bit string literals, though it might be unusual to have two apparently independent literal types fold into the same storage type.
This commit is contained in:
parent
cc8839a10b
commit
90edb265e3
|
@ -1,30 +1,30 @@
|
|||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.3 2002/06/22 02:04:55 thomas Exp $
|
||||
-->
|
||||
|
||||
<appendix id="features">
|
||||
<title>SQL99 Feature List</title>
|
||||
|
||||
<para>
|
||||
<acronym>SQL92</acronym> defined three feature sets for
|
||||
compliance: basic, intermediate, and advanced. Most database
|
||||
products claiming <acronym>SQL</acronym> standards compliance were
|
||||
compliant at only the basic level, since the entire set of
|
||||
intermediate and advanced features was either too voluminous or in
|
||||
conflict with legacy behaviors.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<acronym>SQL99</acronym> defines a large set of individual
|
||||
features rather than the ineffectively broad three levels found in
|
||||
<acronym>SQL92</acronym>. We provide a list of supported features,
|
||||
followed by a list of the features defined in SQL99 which are not
|
||||
yet supported in PostgreSQL.
|
||||
</para>
|
||||
|
||||
<sect1 id="features-sql99">
|
||||
<title>Supported Features</title>
|
||||
|
||||
<para>
|
||||
<acronym>SQL92</acronym> defined three feature sets for
|
||||
compliance: basic, intermediate, and advanced. Most database
|
||||
products claiming <acronym>SQL</acronym> standards compliance were
|
||||
compliant at only the basic level, since the entire set of
|
||||
intermediate and advanced features was either too voluminous or in
|
||||
conflict with legacy behaviors.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<acronym>SQL99</acronym> defines a large set of individual
|
||||
features rather than the ineffectively broad three levels found in
|
||||
<acronym>SQL92</acronym>. We provide a list of supported features,
|
||||
followed by a list of the features defined in SQL99 which are not
|
||||
yet supported in PostgreSQL.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<informaltable>
|
||||
<tgroup cols="3">
|
||||
|
@ -1132,6 +1132,11 @@ $Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 tho
|
|||
<entry>Array as result type of functions</entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>S211</entry>
|
||||
<entry>User-defined cast functions</entry>
|
||||
<entry>CREATE CAST(type AS type)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>T031</entry>
|
||||
<entry>BOOLEAN data type</entry>
|
||||
|
@ -1147,11 +1152,6 @@ $Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 tho
|
|||
<entry>DISTINCT predicate</entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>T171</entry>
|
||||
<entry>LIKE clause in table definition</entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>T191</entry>
|
||||
<entry>Referential action RESTRICT</entry>
|
||||
|
@ -1318,7 +1318,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 tho
|
|||
<entry>E152-02</entry>
|
||||
<entry>SET TRANSACTION statement: READ ONLY and READ WRITE
|
||||
clauses</entry>
|
||||
<entry></entry>
|
||||
<entry>Syntax accepted; READ ONLY not supported</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>E171</entry>
|
||||
|
@ -1621,11 +1621,6 @@ $Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 tho
|
|||
<entry>Subtype treatment</entry>
|
||||
<entry>TREAT(expr AS type)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>S211</entry>
|
||||
<entry>User-defined cast functions</entry>
|
||||
<entry>CREATE CAST(type AS type) WITH</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>S231</entry>
|
||||
<entry>Structured type locators</entry>
|
||||
|
@ -1712,6 +1707,11 @@ $Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 tho
|
|||
<entry>Recursive query</entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>T171</entry>
|
||||
<entry>LIKE clause in table definition</entry>
|
||||
<entry>CREATE TABLE T1 (LIKE T2)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>T211-05</entry>
|
||||
<entry>Ability to specify a search condition that must be true
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.333 2002/06/20 20:29:32 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.334 2002/06/22 02:04:45 thomas Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
|
@ -90,6 +90,7 @@ static Node *makeIntConst(int val);
|
|||
static Node *makeFloatConst(char *str);
|
||||
static Node *makeAConst(Value *v);
|
||||
static Node *makeRowExpr(List *opr, List *largs, List *rargs);
|
||||
static DefElem *makeDefElem(char *name, Node *arg);
|
||||
static SelectStmt *findLeftmostSelect(SelectStmt *node);
|
||||
static void insertSelectOptions(SelectStmt *stmt,
|
||||
List *sortClause, List *forUpdate,
|
||||
|
@ -163,7 +164,7 @@ static void doNegateFloat(Value *v);
|
|||
%type <defelt> createdb_opt_item, copy_opt_item
|
||||
|
||||
%type <ival> opt_lock, lock_type
|
||||
%type <boolean> opt_force, opt_or_replace
|
||||
%type <boolean> opt_force, opt_or_replace
|
||||
|
||||
%type <list> user_list
|
||||
|
||||
|
@ -226,7 +227,7 @@ static void doNegateFloat(Value *v);
|
|||
%type <boolean> opt_arg, TriggerForType, OptTemp, OptWithOids
|
||||
|
||||
%type <list> for_update_clause, opt_for_update_clause, update_list
|
||||
%type <boolean> opt_all
|
||||
%type <boolean> opt_all
|
||||
|
||||
%type <node> join_outer, join_qual
|
||||
%type <jtype> join_type
|
||||
|
@ -299,7 +300,7 @@ static void doNegateFloat(Value *v);
|
|||
%type <keyword> unreserved_keyword, func_name_keyword
|
||||
%type <keyword> col_name_keyword, reserved_keyword
|
||||
|
||||
%type <node> TableConstraint
|
||||
%type <node> TableConstraint, TableLikeClause
|
||||
%type <list> ColQualList
|
||||
%type <node> ColConstraint, ColConstraintElem, ConstraintAttr
|
||||
%type <ival> key_actions, key_delete, key_update, key_reference
|
||||
|
@ -320,7 +321,7 @@ static void doNegateFloat(Value *v);
|
|||
/* ordinary key words in alphabetical order */
|
||||
%token <keyword> ABORT_TRANS, ABSOLUTE, ACCESS, ACTION, ADD, AFTER,
|
||||
AGGREGATE, ALL, ALTER, ANALYSE, ANALYZE, AND, ANY, AS, ASC,
|
||||
ASSERTION, AT, AUTHORIZATION,
|
||||
ASSERTION, ASSIGNMENT, AT, AUTHORIZATION,
|
||||
|
||||
BACKWARD, BEFORE, BEGIN_TRANS, BETWEEN, BIGINT, BINARY, BIT, BOTH,
|
||||
BOOLEAN, BY,
|
||||
|
@ -377,7 +378,7 @@ static void doNegateFloat(Value *v);
|
|||
|
||||
SCHEMA, SCROLL, SECOND_P, SECURITY, SELECT, SEQUENCE,
|
||||
SERIALIZABLE, SESSION, SESSION_USER, SET, SETOF, SHARE,
|
||||
SHOW, SIMILAR, SMALLINT, SOME, STABLE, START, STATEMENT,
|
||||
SHOW, SIMILAR, SIMPLE, SMALLINT, SOME, STABLE, START, STATEMENT,
|
||||
STATISTICS, STDIN, STDOUT, STORAGE, STRICT, SUBSTRING,
|
||||
SYSID,
|
||||
|
||||
|
@ -391,7 +392,7 @@ static void doNegateFloat(Value *v);
|
|||
VACUUM, VALID, VALIDATOR, VALUES, VARCHAR, VARYING,
|
||||
VERBOSE, VERSION, VIEW, VOLATILE,
|
||||
|
||||
WHEN, WHERE, WITH, WITHOUT, WORK,
|
||||
WHEN, WHERE, WITH, WITHOUT, WORK, WRITE,
|
||||
|
||||
YEAR_P,
|
||||
|
||||
|
@ -616,63 +617,43 @@ OptUserList:
|
|||
OptUserElem:
|
||||
PASSWORD Sconst
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "password";
|
||||
$$->arg = (Node *)makeString($2);
|
||||
$$ = makeDefElem("password", (Node *)makeString($2));
|
||||
}
|
||||
| ENCRYPTED PASSWORD Sconst
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "encryptedPassword";
|
||||
$$->arg = (Node *)makeString($3);
|
||||
$$ = makeDefElem("encryptedPassword", (Node *)makeString($3));
|
||||
}
|
||||
| UNENCRYPTED PASSWORD Sconst
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "unencryptedPassword";
|
||||
$$->arg = (Node *)makeString($3);
|
||||
$$ = makeDefElem("unencryptedPassword", (Node *)makeString($3));
|
||||
}
|
||||
| SYSID Iconst
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "sysid";
|
||||
$$->arg = (Node *)makeInteger($2);
|
||||
$$ = makeDefElem("sysid", (Node *)makeInteger($2));
|
||||
}
|
||||
| CREATEDB
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "createdb";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
$$ = makeDefElem("createdb", (Node *)makeInteger(TRUE));
|
||||
}
|
||||
| NOCREATEDB
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "createdb";
|
||||
$$->arg = (Node *)makeInteger(FALSE);
|
||||
$$ = makeDefElem("createdb", (Node *)makeInteger(FALSE));
|
||||
}
|
||||
| CREATEUSER
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "createuser";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
{
|
||||
$$ = makeDefElem("createuser", (Node *)makeInteger(TRUE));
|
||||
}
|
||||
| NOCREATEUSER
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "createuser";
|
||||
$$->arg = (Node *)makeInteger(FALSE);
|
||||
{
|
||||
$$ = makeDefElem("createuser", (Node *)makeInteger(FALSE));
|
||||
}
|
||||
| IN_P GROUP_P user_list
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "groupElts";
|
||||
$$->arg = (Node *)$3;
|
||||
{
|
||||
$$ = makeDefElem("groupElts", (Node *)$3);
|
||||
}
|
||||
| VALID UNTIL Sconst
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "validUntil";
|
||||
$$->arg = (Node *)makeString($3);
|
||||
{
|
||||
$$ = makeDefElem("validUntil", (Node *)makeString($3));
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -709,16 +690,12 @@ OptGroupList:
|
|||
|
||||
OptGroupElem:
|
||||
USER user_list
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "userElts";
|
||||
$$->arg = (Node *)$2;
|
||||
{
|
||||
$$ = makeDefElem("userElts", (Node *)$2);
|
||||
}
|
||||
| SYSID Iconst
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "sysid";
|
||||
$$->arg = (Node *)makeInteger($2);
|
||||
$$ = makeDefElem("sysid", (Node *)makeInteger($2));
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -881,7 +858,7 @@ set_rest: ColId TO var_list_or_default
|
|||
n->args = makeList1($3);
|
||||
$$ = n;
|
||||
}
|
||||
| TRANSACTION ISOLATION LEVEL opt_level
|
||||
| TRANSACTION ISOLATION LEVEL opt_level opt_mode
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->name = "TRANSACTION ISOLATION LEVEL";
|
||||
|
@ -940,6 +917,16 @@ opt_level: READ COMMITTED { $$ = "read committed"; }
|
|||
| SERIALIZABLE { $$ = "serializable"; }
|
||||
;
|
||||
|
||||
opt_mode: READ WRITE
|
||||
{}
|
||||
| READ ONLY
|
||||
{
|
||||
elog(ERROR, "SET TRANSACTION/READ ONLY not yet supported");
|
||||
}
|
||||
| /*EMPTY*/
|
||||
{}
|
||||
;
|
||||
|
||||
opt_boolean:
|
||||
TRUE_P { $$ = "true"; }
|
||||
| FALSE_P { $$ = "false"; }
|
||||
|
@ -1130,11 +1117,8 @@ AlterTableStmt:
|
|||
n->def = $6;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* ALTER TABLE <relation> ALTER [COLUMN] <colname>
|
||||
* {SET DEFAULT <expr>|DROP DEFAULT}
|
||||
*/
|
||||
| ALTER TABLE relation_expr ALTER opt_column
|
||||
ColId alter_column_default
|
||||
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
|
||||
| ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default
|
||||
{
|
||||
AlterTableStmt *n = makeNode(AlterTableStmt);
|
||||
n->subtype = 'T';
|
||||
|
@ -1143,11 +1127,8 @@ AlterTableStmt:
|
|||
n->def = $7;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* ALTER TABLE <relation> ALTER [COLUMN] <colname>
|
||||
* DROP NOT NULL
|
||||
*/
|
||||
| ALTER TABLE relation_expr ALTER opt_column
|
||||
ColId DROP NOT NULL_P
|
||||
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> DROP NOT NULL */
|
||||
| ALTER TABLE relation_expr ALTER opt_column ColId DROP NOT NULL_P
|
||||
{
|
||||
AlterTableStmt *n = makeNode(AlterTableStmt);
|
||||
n->subtype = 'N';
|
||||
|
@ -1155,11 +1136,8 @@ AlterTableStmt:
|
|||
n->name = $6;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* ALTER TABLE <relation> ALTER [COLUMN] <colname>
|
||||
* SET NOT NULL
|
||||
*/
|
||||
| ALTER TABLE relation_expr ALTER opt_column ColId
|
||||
SET NOT NULL_P
|
||||
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET NOT NULL */
|
||||
| ALTER TABLE relation_expr ALTER opt_column ColId SET NOT NULL_P
|
||||
{
|
||||
AlterTableStmt *n = makeNode(AlterTableStmt);
|
||||
n->subtype = 'O';
|
||||
|
@ -1167,11 +1145,8 @@ AlterTableStmt:
|
|||
n->name = $6;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* ALTER TABLE <relation> ALTER [COLUMN] <colname>
|
||||
* SET STATISTICS <Iconst>
|
||||
*/
|
||||
| ALTER TABLE relation_expr ALTER opt_column ColId
|
||||
SET STATISTICS Iconst
|
||||
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <Iconst> */
|
||||
| ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS Iconst
|
||||
{
|
||||
AlterTableStmt *n = makeNode(AlterTableStmt);
|
||||
n->subtype = 'S';
|
||||
|
@ -1180,9 +1155,7 @@ AlterTableStmt:
|
|||
n->def = (Node *) makeInteger($9);
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* ALTER TABLE <relation> ALTER [COLUMN] <colname>
|
||||
* SET STORAGE <storagemode>
|
||||
*/
|
||||
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
|
||||
| ALTER TABLE relation_expr ALTER opt_column ColId
|
||||
SET STORAGE ColId
|
||||
{
|
||||
|
@ -1193,9 +1166,7 @@ AlterTableStmt:
|
|||
n->def = (Node *) makeString($9);
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* ALTER TABLE <relation> DROP [COLUMN] <colname>
|
||||
* {RESTRICT|CASCADE}
|
||||
*/
|
||||
/* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
|
||||
| ALTER TABLE relation_expr DROP opt_column ColId drop_behavior
|
||||
{
|
||||
AlterTableStmt *n = makeNode(AlterTableStmt);
|
||||
|
@ -1214,9 +1185,7 @@ AlterTableStmt:
|
|||
n->def = $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* ALTER TABLE <relation> DROP CONSTRAINT <name>
|
||||
* {RESTRICT|CASCADE}
|
||||
*/
|
||||
/* ALTER TABLE <relation> DROP CONSTRAINT <name> {RESTRICT|CASCADE} */
|
||||
| ALTER TABLE relation_expr DROP CONSTRAINT name drop_behavior
|
||||
{
|
||||
AlterTableStmt *n = makeNode(AlterTableStmt);
|
||||
|
@ -1479,6 +1448,7 @@ OptTableElementList:
|
|||
|
||||
OptTableElement:
|
||||
columnDef { $$ = $1; }
|
||||
| TableLikeClause { $$ = $1; }
|
||||
| TableConstraint { $$ = $1; }
|
||||
;
|
||||
|
||||
|
@ -1667,6 +1637,19 @@ ConstraintAttr:
|
|||
;
|
||||
|
||||
|
||||
/* SQL99 supports wholesale borrowing of a table definition via the LIKE clause.
|
||||
* This seems to be a poor man's inheritance capability, with the resulting
|
||||
* tables completely decoupled except for the original commonality in definitions.
|
||||
* Seems to have much in common with CREATE TABLE AS. - thomas 2002-06-19
|
||||
*/
|
||||
TableLikeClause: LIKE any_name
|
||||
{
|
||||
elog(ERROR, "LIKE in table definitions not yet supported");
|
||||
$$ = NULL;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/* ConstraintElem specifies constraint syntax which is not embedded into
|
||||
* a column definition. ColConstraintElem specifies the embedded form.
|
||||
* - thomas 1997-12-03
|
||||
|
@ -1761,16 +1744,23 @@ columnElem: ColId
|
|||
}
|
||||
;
|
||||
|
||||
key_match: MATCH FULL { $$ = "FULL"; }
|
||||
| MATCH PARTIAL
|
||||
{
|
||||
elog(ERROR, "FOREIGN KEY/MATCH PARTIAL not yet implemented");
|
||||
$$ = "PARTIAL";
|
||||
}
|
||||
| /*EMPTY*/
|
||||
{
|
||||
$$ = "UNSPECIFIED";
|
||||
}
|
||||
key_match: MATCH FULL
|
||||
{
|
||||
$$ = "FULL";
|
||||
}
|
||||
| MATCH PARTIAL
|
||||
{
|
||||
elog(ERROR, "FOREIGN KEY/MATCH PARTIAL not yet implemented");
|
||||
$$ = "PARTIAL";
|
||||
}
|
||||
| MATCH SIMPLE
|
||||
{
|
||||
$$ = "UNSPECIFIED";
|
||||
}
|
||||
| /*EMPTY*/
|
||||
{
|
||||
$$ = "UNSPECIFIED";
|
||||
}
|
||||
;
|
||||
|
||||
key_actions:
|
||||
|
@ -1882,39 +1872,27 @@ OptSeqList: OptSeqList OptSeqElem { $$ = lappend($1, $2); }
|
|||
|
||||
OptSeqElem: CACHE NumericOnly
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "cache";
|
||||
$$->arg = (Node *)$2;
|
||||
$$ = makeDefElem("cache", (Node *)$2);
|
||||
}
|
||||
| CYCLE
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "cycle";
|
||||
$$->arg = (Node *)NULL;
|
||||
$$ = makeDefElem("cycle", (Node *)NULL);
|
||||
}
|
||||
| INCREMENT NumericOnly
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "increment";
|
||||
$$->arg = (Node *)$2;
|
||||
$$ = makeDefElem("increment", (Node *)$2);
|
||||
}
|
||||
| MAXVALUE NumericOnly
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "maxvalue";
|
||||
$$->arg = (Node *)$2;
|
||||
$$ = makeDefElem("maxvalue", (Node *)$2);
|
||||
}
|
||||
| MINVALUE NumericOnly
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "minvalue";
|
||||
$$->arg = (Node *)$2;
|
||||
$$ = makeDefElem("minvalue", (Node *)$2);
|
||||
}
|
||||
| START NumericOnly
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "start";
|
||||
$$->arg = (Node *)$2;
|
||||
$$ = makeDefElem("start", (Node *)$2);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -2275,15 +2253,11 @@ def_list: def_elem { $$ = makeList1($1); }
|
|||
|
||||
def_elem: ColLabel '=' def_arg
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = $1;
|
||||
$$->arg = (Node *)$3;
|
||||
$$ = makeDefElem($1, (Node *)$3);
|
||||
}
|
||||
| ColLabel
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = $1;
|
||||
$$->arg = (Node *)NULL;
|
||||
$$ = makeDefElem($1, (Node *)NULL);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -2906,6 +2880,15 @@ RecipeStmt: EXECUTE RECIPE recipe_name
|
|||
* as <filename or code in language as appropriate>
|
||||
* language <lang> [with parameters]
|
||||
*
|
||||
* CAST() form allowing all options from the CREATE FUNCTION form:
|
||||
* create [or replace] cast (<type> as <type>)
|
||||
* as <filename or code in language as appropriate>
|
||||
* language <lang> [with parameters]
|
||||
*
|
||||
* SQL99 CAST() form (requires a function to be previously defined):
|
||||
* create [or replace] cast (<type> as <type>)
|
||||
* with function fname (<type>) [as assignment]
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
CreateFunctionStmt:
|
||||
|
@ -2921,6 +2904,63 @@ CreateFunctionStmt:
|
|||
n->withClause = $9;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* CREATE CAST SQL99 standard form */
|
||||
| CREATE opt_or_replace CAST '(' func_type AS func_type ')'
|
||||
WITH FUNCTION func_name func_args opt_assignment opt_definition
|
||||
{
|
||||
CreateFunctionStmt *n;
|
||||
char buf[256];
|
||||
n = makeNode(CreateFunctionStmt);
|
||||
n->replace = $2;
|
||||
n->funcname = $7->names;
|
||||
n->argTypes = makeList1($5);
|
||||
n->returnType = $7;
|
||||
/* expand this into a string of SQL language */
|
||||
strcpy(buf, "select ");
|
||||
strcat(buf, ((Value *)lfirst($11))->val.str);
|
||||
strcat(buf, "($1)");
|
||||
n->options = lappend($14, makeDefElem("as", (Node *)makeList1(makeString(pstrdup(buf)))));
|
||||
/* make sure that this will allow implicit casting */
|
||||
n->options = lappend(n->options,
|
||||
makeDefElem("implicit", (Node *)makeInteger(TRUE)));
|
||||
/* and mention that this is SQL language */
|
||||
n->options = lappend(n->options,
|
||||
makeDefElem("language", (Node *)makeString(pstrdup("sql"))));
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* CREATE CAST SQL99 minimally variant form */
|
||||
| CREATE opt_or_replace CAST '(' func_type AS func_type ')'
|
||||
WITH FUNCTION func_name func_args AS Sconst opt_definition
|
||||
{
|
||||
CreateFunctionStmt *n;
|
||||
n = makeNode(CreateFunctionStmt);
|
||||
n->replace = $2;
|
||||
n->funcname = $7->names;
|
||||
n->argTypes = makeList1($5);
|
||||
n->returnType = $7;
|
||||
n->options = lappend($15, makeDefElem("as", (Node *)lcons(makeList1(makeString($14)), $11)));
|
||||
/* make sure that this will allow implicit casting */
|
||||
n->options = lappend(n->options,
|
||||
makeDefElem("implicit", (Node *)makeInteger(TRUE)));
|
||||
n->options = lappend(n->options,
|
||||
makeDefElem("language", (Node *)makeString(pstrdup("c"))));
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* CREATE CAST with mostly CREATE FUNCTION clauses */
|
||||
| CREATE opt_or_replace CAST '(' func_type AS func_type ')'
|
||||
createfunc_opt_list opt_definition
|
||||
{
|
||||
CreateFunctionStmt *n;
|
||||
n = makeNode(CreateFunctionStmt);
|
||||
n->replace = $2;
|
||||
n->funcname = $7->names;
|
||||
n->argTypes = makeList1($5);
|
||||
n->returnType = $7;
|
||||
/* make sure that this will allow implicit casting */
|
||||
n->options = lappend($9, makeDefElem("implicit", (Node *)makeInteger(TRUE)));
|
||||
n->withClause = $10;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
opt_or_replace:
|
||||
|
@ -2998,81 +3038,55 @@ createfunc_opt_list:
|
|||
createfunc_opt_item:
|
||||
AS func_as
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "as";
|
||||
$$->arg = (Node *)$2;
|
||||
$$ = makeDefElem("as", (Node *)$2);
|
||||
}
|
||||
| LANGUAGE ColId_or_Sconst
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "language";
|
||||
$$->arg = (Node *)makeString($2);
|
||||
$$ = makeDefElem("language", (Node *)makeString($2));
|
||||
}
|
||||
| IMMUTABLE
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "volatility";
|
||||
$$->arg = (Node *)makeString("immutable");
|
||||
$$ = makeDefElem("volatility", (Node *)makeString("immutable"));
|
||||
}
|
||||
| STABLE
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "volatility";
|
||||
$$->arg = (Node *)makeString("stable");
|
||||
$$ = makeDefElem("volatility", (Node *)makeString("stable"));
|
||||
}
|
||||
| VOLATILE
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "volatility";
|
||||
$$->arg = (Node *)makeString("volatile");
|
||||
$$ = makeDefElem("volatility", (Node *)makeString("volatile"));
|
||||
}
|
||||
| CALLED ON NULL_P INPUT
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "strict";
|
||||
$$->arg = (Node *)makeInteger(FALSE);
|
||||
$$ = makeDefElem("strict", (Node *)makeInteger(FALSE));
|
||||
}
|
||||
| RETURNS NULL_P ON NULL_P INPUT
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "strict";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
$$ = makeDefElem("strict", (Node *)makeInteger(TRUE));
|
||||
}
|
||||
| STRICT
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "strict";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
$$ = makeDefElem("strict", (Node *)makeInteger(TRUE));
|
||||
}
|
||||
| EXTERNAL SECURITY DEFINER
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "security";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
$$ = makeDefElem("security", (Node *)makeInteger(TRUE));
|
||||
}
|
||||
| EXTERNAL SECURITY INVOKER
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "security";
|
||||
$$->arg = (Node *)makeInteger(FALSE);
|
||||
$$ = makeDefElem("security", (Node *)makeInteger(FALSE));
|
||||
}
|
||||
| SECURITY DEFINER
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "security";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
$$ = makeDefElem("security", (Node *)makeInteger(TRUE));
|
||||
}
|
||||
| SECURITY INVOKER
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "security";
|
||||
$$->arg = (Node *)makeInteger(FALSE);
|
||||
$$ = makeDefElem("security", (Node *)makeInteger(FALSE));
|
||||
}
|
||||
| IMPLICIT CAST
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "implicit";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
$$ = makeDefElem("implicit", (Node *)makeInteger(TRUE));
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -3088,6 +3102,10 @@ opt_definition:
|
|||
| /*EMPTY*/ { $$ = NIL; }
|
||||
;
|
||||
|
||||
opt_assignment: AS ASSIGNMENT {}
|
||||
| /*EMPTY*/ {}
|
||||
;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -3100,11 +3118,22 @@ opt_definition:
|
|||
*****************************************************************************/
|
||||
|
||||
RemoveFuncStmt:
|
||||
DROP FUNCTION func_name func_args
|
||||
DROP FUNCTION func_name func_args opt_drop_behavior
|
||||
{
|
||||
RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
|
||||
n->funcname = $3;
|
||||
n->args = $4;
|
||||
if ($5 != RESTRICT)
|
||||
elog(ERROR, "DROP FUNCTION/CASCADE not supported");
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| DROP CAST '(' func_type AS func_type ')' opt_drop_behavior
|
||||
{
|
||||
RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
|
||||
n->funcname = $6->names;
|
||||
n->args = makeList1($4);
|
||||
if ($8 != RESTRICT)
|
||||
elog(ERROR, "DROP CAST/CASCADE not supported");
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
@ -3425,7 +3454,7 @@ opt_chain: AND NO CHAIN {}
|
|||
* if they don't support it. So we can't just ignore it.
|
||||
* - thomas 2000-08-06
|
||||
*/
|
||||
elog(ERROR, "COMMIT / CHAIN not yet supported");
|
||||
elog(ERROR, "COMMIT/AND CHAIN not yet supported");
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -4146,6 +4175,7 @@ opt_table: TABLE {}
|
|||
;
|
||||
|
||||
opt_all: ALL { $$ = TRUE; }
|
||||
| DISTINCT { $$ = FALSE; }
|
||||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
;
|
||||
|
||||
|
@ -6560,6 +6590,7 @@ unreserved_keyword:
|
|||
| AGGREGATE
|
||||
| ALTER
|
||||
| ASSERTION
|
||||
| ASSIGNMENT
|
||||
| AT
|
||||
| BACKWARD
|
||||
| BEFORE
|
||||
|
@ -6683,6 +6714,7 @@ unreserved_keyword:
|
|||
| SET
|
||||
| SHARE
|
||||
| SHOW
|
||||
| SIMPLE
|
||||
| STABLE
|
||||
| START
|
||||
| STATEMENT
|
||||
|
@ -6717,6 +6749,7 @@ unreserved_keyword:
|
|||
| VOLATILE
|
||||
| WITH
|
||||
| WITHOUT
|
||||
| WRITE
|
||||
| WORK
|
||||
| YEAR_P
|
||||
| ZONE
|
||||
|
@ -6977,6 +7010,19 @@ makeAConst(Value *v)
|
|||
return n;
|
||||
}
|
||||
|
||||
/* makeDefElem()
|
||||
* Create a DefElem node and set contents.
|
||||
* Could be moved to nodes/makefuncs.c if this is useful elsewhere.
|
||||
*/
|
||||
static DefElem *
|
||||
makeDefElem(char *name, Node *arg)
|
||||
{
|
||||
DefElem *f = makeNode(DefElem);
|
||||
f->defname = name;
|
||||
f->arg = arg;
|
||||
return f;
|
||||
}
|
||||
|
||||
/* makeRowExpr()
|
||||
* Generate separate operator nodes for a single row descriptor expression.
|
||||
* Perhaps this should go deeper in the parser someday...
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.116 2002/06/20 20:29:32 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.117 2002/06/22 02:04:45 thomas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -44,6 +44,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||
{"as", AS},
|
||||
{"asc", ASC},
|
||||
{"assertion", ASSERTION},
|
||||
{"assignment", ASSIGNMENT},
|
||||
{"at", AT},
|
||||
{"authorization", AUTHORIZATION},
|
||||
{"backward", BACKWARD},
|
||||
|
@ -258,6 +259,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||
{"share", SHARE},
|
||||
{"show", SHOW},
|
||||
{"similar", SIMILAR},
|
||||
{"simple", SIMPLE},
|
||||
{"smallint", SMALLINT},
|
||||
{"some", SOME},
|
||||
{"stable", STABLE},
|
||||
|
@ -312,6 +314,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||
{"with", WITH},
|
||||
{"without", WITHOUT},
|
||||
{"work", WORK},
|
||||
{"write", WRITE},
|
||||
{"year", YEAR_P},
|
||||
{"zone", ZONE},
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.96 2002/06/20 20:29:33 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.97 2002/06/22 02:04:45 thomas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -107,8 +107,8 @@ unsigned char unescape_single_char(unsigned char c);
|
|||
|
||||
/* Bit string
|
||||
*/
|
||||
xbstart [bB]{quote}
|
||||
xbstop {quote}
|
||||
xbstart [bB]{quote}
|
||||
xbstop {quote}
|
||||
xbinside [^']*
|
||||
xbcat {quote}{whitespace_with_newline}{quote}
|
||||
|
||||
|
@ -119,6 +119,10 @@ xhstop {quote}
|
|||
xhinside [^']+
|
||||
xhcat {quote}{whitespace_with_newline}{quote}
|
||||
|
||||
/* National character
|
||||
*/
|
||||
xnstart [nN]{quote}
|
||||
|
||||
/* Extended quote
|
||||
* xqdouble implements SQL92 embedded quote
|
||||
* xqcat allows strings to cross input lines
|
||||
|
@ -286,6 +290,10 @@ other .
|
|||
<xc><<EOF>> { yyerror("unterminated /* comment"); }
|
||||
|
||||
{xbstart} {
|
||||
/* Binary bit type.
|
||||
* Should be passing the type forward into the parser
|
||||
* rather than trying to embed it into the string.
|
||||
*/
|
||||
token_start = yytext;
|
||||
BEGIN(xb);
|
||||
startlit();
|
||||
|
@ -309,6 +317,10 @@ other .
|
|||
<xb><<EOF>> { yyerror("unterminated bit string literal"); }
|
||||
|
||||
{xhstart} {
|
||||
/* Hexadecimal bit type.
|
||||
* Should be passing the type forward into the parser
|
||||
* rather than trying to embed it into the string.
|
||||
*/
|
||||
token_start = yytext;
|
||||
BEGIN(xh);
|
||||
startlit();
|
||||
|
@ -332,6 +344,17 @@ other .
|
|||
}
|
||||
<xh><<EOF>> { yyerror("unterminated hexadecimal integer"); }
|
||||
|
||||
{xnstart} {
|
||||
/* National character.
|
||||
* Need to remember type info to flow it forward into the parser.
|
||||
* Not yet implemented. - thomas 2002-06-17
|
||||
*/
|
||||
token_start = yytext;
|
||||
BEGIN(xq);
|
||||
startlit();
|
||||
}
|
||||
|
||||
|
||||
{xqstart} {
|
||||
token_start = yytext;
|
||||
BEGIN(xq);
|
||||
|
|
Loading…
Reference in New Issue