mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Revert "Support more object types within CREATE SCHEMA".
This reverts commitd516974840, along with parts of commit049b742daa("psql: Tighten heuristics for BEGIN/END within CREATE SCHEMA"). While there's nothing particularly wrong withd51697484in itself, it depends ona9c350d9e("Don't try to re-order the subcommands of CREATE SCHEMA"), and concerns have been raised that the compatibility impact of that outweighs the benefit of allowing more object types within CREATE SCHEMA. It's not possible to revert049b742daverbatim, because the CVE-2026-6464 patches3045a25ba("Teach psql to skip in-line COPY ... FROM STDIN data after a failure") andcf754f741("Save/restore more lexer state when skipping text due to \if") depend on infrastructure it added. Instead, rip out just the bits specifically needed to parse CREATE FUNCTION within CREATE SCHEMA. This results in lexer code that matches v18-and-earlier as modified by CVE-2026-6464. Author: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/20260904180712.cc.noahmisch@microsoft.com Backpatch-through: 19
This commit is contained in:
@@ -100,27 +100,12 @@ CREATE SCHEMA IF NOT EXISTS AUTHORIZATION <replaceable class="parameter">role_sp
|
||||
<listitem>
|
||||
<para>
|
||||
An SQL statement defining an object to be created within the
|
||||
schema. Currently, only
|
||||
<command>CREATE AGGREGATE</command>,
|
||||
<command>CREATE COLLATION</command>,
|
||||
<command>CREATE DOMAIN</command>,
|
||||
<command>CREATE FUNCTION</command>,
|
||||
<command>CREATE INDEX</command>,
|
||||
<command>CREATE OPERATOR</command>,
|
||||
<command>CREATE PROCEDURE</command>,
|
||||
<command>CREATE SEQUENCE</command>,
|
||||
<command>CREATE TABLE</command>,
|
||||
<command>CREATE TEXT SEARCH CONFIGURATION</command>,
|
||||
<command>CREATE TEXT SEARCH DICTIONARY</command>,
|
||||
<command>CREATE TEXT SEARCH PARSER</command>,
|
||||
<command>CREATE TEXT SEARCH TEMPLATE</command>,
|
||||
<command>CREATE TRIGGER</command>,
|
||||
<command>CREATE TYPE</command>,
|
||||
<command>CREATE VIEW</command>,
|
||||
and <command>GRANT</command> are accepted as clauses
|
||||
schema. Currently, only <command>CREATE
|
||||
TABLE</command>, <command>CREATE VIEW</command>, <command>CREATE
|
||||
INDEX</command>, <command>CREATE SEQUENCE</command>, <command>CREATE
|
||||
TRIGGER</command> and <command>GRANT</command> are accepted as clauses
|
||||
within <command>CREATE SCHEMA</command>. Other kinds of objects may
|
||||
be created within the schema in separate commands after the schema
|
||||
is created.
|
||||
be created in separate commands after the schema is created.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -1642,11 +1642,8 @@ OptSchemaEltList:
|
||||
schema_stmt:
|
||||
CreateStmt
|
||||
| IndexStmt
|
||||
| CreateDomainStmt
|
||||
| CreateFunctionStmt
|
||||
| CreateSeqStmt
|
||||
| CreateTrigStmt
|
||||
| DefineStmt
|
||||
| GrantStmt
|
||||
| ViewStmt
|
||||
;
|
||||
|
||||
@@ -124,8 +124,6 @@ static void transformConstraintAttrs(ParseState *pstate,
|
||||
static void transformColumnType(CreateStmtContext *cxt, ColumnDef *column);
|
||||
static void checkSchemaNameRV(ParseState *pstate, const char *context_schema,
|
||||
RangeVar *relation);
|
||||
static void checkSchemaNameList(const char *context_schema,
|
||||
List *qualified_name);
|
||||
static CreateStmt *transformCreateSchemaCreateTable(ParseState *pstate,
|
||||
CreateStmt *stmt,
|
||||
List **fk_elements);
|
||||
@@ -4189,68 +4187,6 @@ transformCreateSchemaStmtElements(ParseState *pstate, List *schemaElts,
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CreateDomainStmt:
|
||||
{
|
||||
CreateDomainStmt *elp = (CreateDomainStmt *) element;
|
||||
|
||||
checkSchemaNameList(schemaName, elp->domainname);
|
||||
elements = lappend(elements, element);
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CreateFunctionStmt:
|
||||
{
|
||||
CreateFunctionStmt *elp = (CreateFunctionStmt *) element;
|
||||
|
||||
checkSchemaNameList(schemaName, elp->funcname);
|
||||
elements = lappend(elements, element);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* CREATE TYPE can produce a DefineStmt, but also
|
||||
* CreateEnumStmt, CreateRangeStmt, and CompositeTypeStmt.
|
||||
* Allowing DefineStmt also provides support for several other
|
||||
* commands: currently, CREATE AGGREGATE, CREATE COLLATION,
|
||||
* CREATE OPERATOR, and text search objects.
|
||||
*/
|
||||
|
||||
case T_DefineStmt:
|
||||
{
|
||||
DefineStmt *elp = (DefineStmt *) element;
|
||||
|
||||
checkSchemaNameList(schemaName, elp->defnames);
|
||||
elements = lappend(elements, element);
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CreateEnumStmt:
|
||||
{
|
||||
CreateEnumStmt *elp = (CreateEnumStmt *) element;
|
||||
|
||||
checkSchemaNameList(schemaName, elp->typeName);
|
||||
elements = lappend(elements, element);
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CreateRangeStmt:
|
||||
{
|
||||
CreateRangeStmt *elp = (CreateRangeStmt *) element;
|
||||
|
||||
checkSchemaNameList(schemaName, elp->typeName);
|
||||
elements = lappend(elements, element);
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CompositeTypeStmt:
|
||||
{
|
||||
CompositeTypeStmt *elp = (CompositeTypeStmt *) element;
|
||||
|
||||
checkSchemaNameRV(pstate, schemaName, elp->typevar);
|
||||
elements = lappend(elements, element);
|
||||
}
|
||||
break;
|
||||
|
||||
case T_GrantStmt:
|
||||
elements = lappend(elements, element);
|
||||
break;
|
||||
@@ -4298,30 +4234,6 @@ checkSchemaNameRV(ParseState *pstate, const char *context_schema,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* checkSchemaNameList
|
||||
* Check schema name in an element of a CREATE SCHEMA command,
|
||||
* where the element's name is given by a List
|
||||
*
|
||||
* Much as above, but we don't have to worry about TEMP.
|
||||
* Sadly, this also means we don't have a parse location to report.
|
||||
*/
|
||||
static void
|
||||
checkSchemaNameList(const char *context_schema, List *qualified_name)
|
||||
{
|
||||
char *obj_schema;
|
||||
char *obj_name;
|
||||
|
||||
DeconstructQualifiedName(qualified_name, &obj_schema, &obj_name);
|
||||
if (obj_schema != NULL &&
|
||||
strcmp(context_schema, obj_schema) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_SCHEMA_DEFINITION),
|
||||
errmsg("CREATE specifies a schema (%s) "
|
||||
"different from the one being created (%s)",
|
||||
obj_schema, context_schema)));
|
||||
}
|
||||
|
||||
/*
|
||||
* transformCreateSchemaCreateTable
|
||||
* Process one CreateStmt for transformCreateSchemaStmtElements.
|
||||
|
||||
@@ -738,8 +738,6 @@ psql_scan_get_lex_state(PsqlScanState state)
|
||||
PsqlScanStateSave *lex_state = pg_malloc_object(PsqlScanStateSave);
|
||||
StaticAssertDecl(sizeof(lex_state->init_idents) == sizeof(state->init_idents),
|
||||
"init_idents array lengths must match");
|
||||
StaticAssertDecl(sizeof(lex_state->sub_idents) == sizeof(state->sub_idents),
|
||||
"sub_idents array lengths must match");
|
||||
|
||||
lex_state->paren_depth = state->paren_depth;
|
||||
lex_state->begin_depth = state->begin_depth;
|
||||
@@ -747,9 +745,6 @@ psql_scan_get_lex_state(PsqlScanState state)
|
||||
lex_state->init_idents_count = state->init_idents_count;
|
||||
memcpy(lex_state->init_idents, state->init_idents,
|
||||
sizeof(lex_state->init_idents));
|
||||
lex_state->sub_idents_count = state->sub_idents_count;
|
||||
memcpy(lex_state->sub_idents, state->sub_idents,
|
||||
sizeof(lex_state->sub_idents));
|
||||
return lex_state;
|
||||
}
|
||||
|
||||
@@ -766,9 +761,6 @@ psql_scan_set_lex_state(PsqlScanState state,
|
||||
state->init_idents_count = lex_state->init_idents_count;
|
||||
memcpy(state->init_idents, lex_state->init_idents,
|
||||
sizeof(state->init_idents));
|
||||
state->sub_idents_count = lex_state->sub_idents_count;
|
||||
memcpy(state->sub_idents, lex_state->sub_idents,
|
||||
sizeof(state->sub_idents));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -2203,11 +2203,7 @@ match_previous_words(int pattern_id,
|
||||
{
|
||||
/* only some object types can be created as part of CREATE SCHEMA */
|
||||
if (HeadMatches("CREATE", "SCHEMA"))
|
||||
COMPLETE_WITH("AGGREGATE", "COLLATION", "DOMAIN", "FUNCTION",
|
||||
"INDEX", "OPERATOR", "PROCEDURE", "SEQUENCE", "TABLE",
|
||||
"TEXT SEARCH CONFIGURATION", "TEXT SEARCH DICTIONARY",
|
||||
"TEXT SEARCH PARSER", "TEXT SEARCH TEMPLATE",
|
||||
"TRIGGER", "TYPE", "VIEW",
|
||||
COMPLETE_WITH("TABLE", "VIEW", "INDEX", "SEQUENCE", "TRIGGER",
|
||||
/* for INDEX and TABLE/SEQUENCE, respectively */
|
||||
"UNIQUE", "UNLOGGED");
|
||||
else
|
||||
@@ -3507,15 +3503,15 @@ match_previous_words(int pattern_id,
|
||||
else if (Matches("CREATE", "DATABASE", MatchAny, "STRATEGY"))
|
||||
COMPLETE_WITH("WAL_LOG", "FILE_COPY");
|
||||
|
||||
/* CREATE DOMAIN --- is allowed inside CREATE SCHEMA, so use TailMatches */
|
||||
else if (TailMatches("CREATE", "DOMAIN", MatchAny))
|
||||
/* CREATE DOMAIN */
|
||||
else if (Matches("CREATE", "DOMAIN", MatchAny))
|
||||
COMPLETE_WITH("AS");
|
||||
else if (TailMatches("CREATE", "DOMAIN", MatchAny, "AS"))
|
||||
else if (Matches("CREATE", "DOMAIN", MatchAny, "AS"))
|
||||
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
|
||||
else if (TailMatches("CREATE", "DOMAIN", MatchAny, "AS", MatchAny))
|
||||
else if (Matches("CREATE", "DOMAIN", MatchAny, "AS", MatchAny))
|
||||
COMPLETE_WITH("COLLATE", "DEFAULT", "CONSTRAINT",
|
||||
"NOT NULL", "NULL", "CHECK (");
|
||||
else if (TailMatches("CREATE", "DOMAIN", MatchAny, "COLLATE"))
|
||||
else if (Matches("CREATE", "DOMAIN", MatchAny, "COLLATE"))
|
||||
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_collations);
|
||||
|
||||
/* CREATE EXTENSION */
|
||||
@@ -3860,10 +3856,10 @@ match_previous_words(int pattern_id,
|
||||
else if (Matches("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny))
|
||||
COMPLETE_WITH("LOCATION");
|
||||
|
||||
/* CREATE TEXT SEARCH --- is allowed inside CREATE SCHEMA, so use TailMatches */
|
||||
else if (TailMatches("CREATE", "TEXT", "SEARCH"))
|
||||
/* CREATE TEXT SEARCH */
|
||||
else if (Matches("CREATE", "TEXT", "SEARCH"))
|
||||
COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
|
||||
else if (TailMatches("CREATE", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
|
||||
else if (Matches("CREATE", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
|
||||
COMPLETE_WITH("(");
|
||||
|
||||
/* CREATE TRANSFORM */
|
||||
|
||||
@@ -959,8 +959,8 @@ other .
|
||||
/* LCOV_EXCL_STOP */
|
||||
|
||||
/*
|
||||
* Record the first few keywords/identifiers of a statement or CREATE
|
||||
* SCHEMA sub-statement in the idents[] array, of length idents_size.
|
||||
* Record the first few keywords/identifiers of a statement
|
||||
* in the idents[] array, of length idents_size.
|
||||
* *idents_count is the number of entries filled so far.
|
||||
*
|
||||
* We record the interesting keywords using their first character, which
|
||||
@@ -976,20 +976,18 @@ psqlscan_record_initial_keyword(const char *identifier,
|
||||
if (*idents_count < idents_size)
|
||||
{
|
||||
/*
|
||||
* What we need to recognize is CREATE [OR REPLACE] FUNCTION/PROCEDURE
|
||||
* and CREATE SCHEMA. Checking for SCHEMA is useless but not harmful
|
||||
* in the CREATE SCHEMA sub-statement case. We record these keywords
|
||||
* in lower case. We also need to recognize COPY ... FROM STDIN.
|
||||
* (Note: the backend grammar doesn't distinguish STDIN from STDOUT,
|
||||
* so we should not do so here either.) We record these keywords in
|
||||
* upper case, to avoid conflicting with the first set.
|
||||
* What we need to recognize is CREATE [OR REPLACE] FUNCTION/PROCEDURE.
|
||||
* We record these keywords in lower case. We also need to recognize
|
||||
* COPY ... FROM STDIN. (Note: the backend grammar doesn't
|
||||
* distinguish STDIN from STDOUT, so we should not do so here either.)
|
||||
* We record these keywords in upper case, to avoid conflicting with
|
||||
* the first set.
|
||||
*/
|
||||
if (pg_strcasecmp(identifier, "create") == 0 ||
|
||||
pg_strcasecmp(identifier, "function") == 0 ||
|
||||
pg_strcasecmp(identifier, "procedure") == 0 ||
|
||||
pg_strcasecmp(identifier, "or") == 0 ||
|
||||
pg_strcasecmp(identifier, "replace") == 0 ||
|
||||
pg_strcasecmp(identifier, "schema") == 0)
|
||||
pg_strcasecmp(identifier, "replace") == 0)
|
||||
idents[*idents_count] = pg_tolower((unsigned char) identifier[0]);
|
||||
else if (pg_strcasecmp(identifier, "copy") == 0 ||
|
||||
pg_strcasecmp(identifier, "from") == 0 ||
|
||||
@@ -1052,10 +1050,8 @@ psqlscan_is_copy_from_stdin(PsqlScanState state)
|
||||
* Short of writing a full parser here, the following heuristic should work.
|
||||
*
|
||||
* We track whether the beginning of the statement matches CREATE [OR REPLACE]
|
||||
* {FUNCTION|PROCEDURE}. For CREATE SCHEMA, track BEGIN .. END blocks only
|
||||
* after recognizing an embedded CREATE [OR REPLACE] {FUNCTION|PROCEDURE}
|
||||
* subcommand. Once one of these conditions holds, count BEGIN and END
|
||||
* pairs. We also have to account for CASE ... END.
|
||||
* {FUNCTION|PROCEDURE}. If so, count BEGIN and END pairs. We also have to
|
||||
* account for CASE ... END.
|
||||
*
|
||||
* 2. Record enough information for psqlscan_is_copy_from_stdin() to recognize
|
||||
* COPY FROM STDIN commands.
|
||||
@@ -1063,19 +1059,13 @@ psqlscan_is_copy_from_stdin(PsqlScanState state)
|
||||
static void
|
||||
psqlscan_track_identifier(PsqlScanState state, const char *identifier)
|
||||
{
|
||||
bool is_create_schema;
|
||||
|
||||
/* None of this needs to happen when we're inside parentheses */
|
||||
if (state->paren_depth != 0)
|
||||
return;
|
||||
|
||||
/* Reset all my state at the start of each new statement */
|
||||
if (state->init_idents_count == 0)
|
||||
{
|
||||
memset(state->init_idents, 0, sizeof(state->init_idents));
|
||||
state->sub_idents_count = 0;
|
||||
memset(state->sub_idents, 0, sizeof(state->sub_idents));
|
||||
}
|
||||
|
||||
/* Record initial keywords if init_idents_count is small enough */
|
||||
psqlscan_record_initial_keyword(identifier,
|
||||
@@ -1084,34 +1074,9 @@ psqlscan_track_identifier(PsqlScanState state, const char *identifier)
|
||||
&state->init_idents_count);
|
||||
|
||||
/*
|
||||
* In CREATE SCHEMA, track identifiers from each top-level CREATE schema
|
||||
* element separately, so that BEGIN/END tracking is enabled only within
|
||||
* CREATE [OR REPLACE] {FUNCTION|PROCEDURE} clauses.
|
||||
* Track BEGIN/CASE/END only when within an appropriate statement.
|
||||
*/
|
||||
is_create_schema = (state->init_idents[0] == 'c' &&
|
||||
state->init_idents[1] == 's');
|
||||
if (is_create_schema &&
|
||||
state->begin_depth == 0)
|
||||
{
|
||||
/* Reset sub-clause state at each top-level CREATE keyword */
|
||||
if (pg_strcasecmp(identifier, "create") == 0)
|
||||
{
|
||||
state->sub_idents_count = 0;
|
||||
memset(state->sub_idents, 0, sizeof(state->sub_idents));
|
||||
}
|
||||
/* ... and record the first few keywords following that */
|
||||
psqlscan_record_initial_keyword(identifier,
|
||||
state->sub_idents,
|
||||
lengthof(state->sub_idents),
|
||||
&state->sub_idents_count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Track BEGIN/CASE/END only when within an appropriate (sub) statement.
|
||||
*/
|
||||
if (psqlscan_is_create_routine(state->init_idents) ||
|
||||
(is_create_schema &&
|
||||
psqlscan_is_create_routine(state->sub_idents)))
|
||||
if (psqlscan_is_create_routine(state->init_idents))
|
||||
{
|
||||
if (pg_strcasecmp(identifier, "begin") == 0)
|
||||
state->begin_depth++;
|
||||
|
||||
@@ -122,9 +122,6 @@ typedef struct PsqlScanStateData
|
||||
int copy_stdin_count; /* number of COPY FROM STDIN commands */
|
||||
int init_idents_count; /* # identifiers since start of statement */
|
||||
char init_idents[8]; /* records the first few identifiers */
|
||||
int sub_idents_count; /* # identifiers since start of a CREATE
|
||||
* SCHEMA element */
|
||||
char sub_idents[4]; /* records the first few of those identifiers */
|
||||
|
||||
/*
|
||||
* Callback functions provided by the program making use of the lexer,
|
||||
@@ -150,9 +147,6 @@ typedef struct PsqlScanStateSave
|
||||
int copy_stdin_count; /* number of COPY FROM STDIN commands */
|
||||
int init_idents_count; /* # identifiers since start of statement */
|
||||
char init_idents[8]; /* records the first few identifiers */
|
||||
int sub_idents_count; /* # identifiers since start of a CREATE
|
||||
* SCHEMA element */
|
||||
char sub_idents[4]; /* records the first few of those identifiers */
|
||||
} PsqlScanStateSave;
|
||||
|
||||
|
||||
|
||||
@@ -13,46 +13,10 @@ CREATE SCHEMA IF NOT EXISTS baz;
|
||||
NOTICE: schema "baz" already exists, skipping
|
||||
CREATE SCHEMA element_test
|
||||
CREATE TABLE foo (id int)
|
||||
CREATE VIEW bar AS SELECT * FROM foo
|
||||
CREATE COLLATION coll (LOCALE="C")
|
||||
CREATE DOMAIN d1 AS INT
|
||||
CREATE FUNCTION et_add(int4, int4) RETURNS int4 LANGUAGE sql
|
||||
AS 'SELECT $1 + $2'
|
||||
CREATE PROCEDURE et_proc(int4, int4)
|
||||
BEGIN ATOMIC SELECT et_add($1,$2); END
|
||||
CREATE TYPE floatrange AS RANGE (subtype = float8, subtype_diff = float8mi)
|
||||
CREATE TYPE ss AS (a int)
|
||||
CREATE TYPE sss
|
||||
CREATE TYPE rainbow AS ENUM ('red', 'orange')
|
||||
CREATE TEXT SEARCH PARSER et_ts_prs
|
||||
(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end,
|
||||
lextypes = prsd_lextype)
|
||||
;
|
||||
CREATE VIEW bar AS SELECT * FROM foo;
|
||||
NOTICE: DDL test: type simple, tag CREATE SCHEMA
|
||||
NOTICE: DDL test: type simple, tag CREATE TABLE
|
||||
NOTICE: DDL test: type simple, tag CREATE VIEW
|
||||
NOTICE: DDL test: type simple, tag CREATE COLLATION
|
||||
NOTICE: DDL test: type simple, tag CREATE DOMAIN
|
||||
NOTICE: DDL test: type simple, tag CREATE FUNCTION
|
||||
NOTICE: DDL test: type simple, tag CREATE PROCEDURE
|
||||
NOTICE: DDL test: type simple, tag CREATE TYPE
|
||||
NOTICE: DDL test: type simple, tag CREATE TYPE
|
||||
NOTICE: DDL test: type simple, tag CREATE TYPE
|
||||
NOTICE: DDL test: type simple, tag CREATE TYPE
|
||||
NOTICE: DDL test: type simple, tag CREATE TEXT SEARCH PARSER
|
||||
DROP SCHEMA element_test CASCADE;
|
||||
NOTICE: drop cascades to 11 other objects
|
||||
DETAIL: drop cascades to table element_test.foo
|
||||
drop cascades to view element_test.bar
|
||||
drop cascades to collation element_test.coll
|
||||
drop cascades to type element_test.d1
|
||||
drop cascades to function element_test.et_add(integer,integer)
|
||||
drop cascades to function element_test.et_proc(integer,integer)
|
||||
drop cascades to type element_test.floatrange
|
||||
drop cascades to type element_test.ss
|
||||
drop cascades to type element_test.sss
|
||||
drop cascades to type element_test.rainbow
|
||||
drop cascades to text search parser element_test.et_ts_prs
|
||||
CREATE SCHEMA regress_schema_1
|
||||
CREATE TABLE t4(
|
||||
b INT,
|
||||
|
||||
@@ -14,23 +14,7 @@ CREATE SCHEMA IF NOT EXISTS baz;
|
||||
|
||||
CREATE SCHEMA element_test
|
||||
CREATE TABLE foo (id int)
|
||||
CREATE VIEW bar AS SELECT * FROM foo
|
||||
CREATE COLLATION coll (LOCALE="C")
|
||||
CREATE DOMAIN d1 AS INT
|
||||
CREATE FUNCTION et_add(int4, int4) RETURNS int4 LANGUAGE sql
|
||||
AS 'SELECT $1 + $2'
|
||||
CREATE PROCEDURE et_proc(int4, int4)
|
||||
BEGIN ATOMIC SELECT et_add($1,$2); END
|
||||
CREATE TYPE floatrange AS RANGE (subtype = float8, subtype_diff = float8mi)
|
||||
CREATE TYPE ss AS (a int)
|
||||
CREATE TYPE sss
|
||||
CREATE TYPE rainbow AS ENUM ('red', 'orange')
|
||||
CREATE TEXT SEARCH PARSER et_ts_prs
|
||||
(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end,
|
||||
lextypes = prsd_lextype)
|
||||
;
|
||||
|
||||
DROP SCHEMA element_test CASCADE;
|
||||
CREATE VIEW bar AS SELECT * FROM foo;
|
||||
|
||||
CREATE SCHEMA regress_schema_1
|
||||
CREATE TABLE t4(
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
CREATE ROLE regress_create_schema_role SUPERUSER;
|
||||
-- Cases where schema creation fails as objects are qualified with a schema
|
||||
-- that does not match with what's expected.
|
||||
-- This checks most object types that include schema qualifications.
|
||||
-- This checks all the object types that include schema qualifications.
|
||||
CREATE SCHEMA AUTHORIZATION regress_create_schema_role
|
||||
CREATE SEQUENCE schema_not_existing.seq;
|
||||
ERROR: CREATE specifies a schema (schema_not_existing) different from the one being created (regress_create_schema_role)
|
||||
@@ -32,10 +32,6 @@ CREATE SCHEMA AUTHORIZATION regress_create_schema_role
|
||||
ERROR: CREATE specifies a schema (schema_not_existing) different from the one being created (regress_create_schema_role)
|
||||
LINE 2: CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_exi...
|
||||
^
|
||||
CREATE SCHEMA AUTHORIZATION regress_create_schema_role
|
||||
CREATE FUNCTION schema_not_existing.func(int) RETURNS int
|
||||
AS 'SELECT $1' LANGUAGE sql;
|
||||
ERROR: CREATE specifies a schema (schema_not_existing) different from the one being created (regress_create_schema_role)
|
||||
-- Again, with a role specification and no schema names.
|
||||
SET ROLE regress_create_schema_role;
|
||||
CREATE SCHEMA AUTHORIZATION CURRENT_ROLE
|
||||
@@ -181,146 +177,5 @@ drop cascades to table regress_schema_fk.t3
|
||||
drop cascades to table regress_schema_fk.t4
|
||||
drop cascades to table regress_schema_fk.t5
|
||||
drop cascades to table regress_schema_fk.t6
|
||||
-- Test miscellaneous object types within CREATE SCHEMA.
|
||||
CREATE SCHEMA regress_schema_misc
|
||||
CREATE AGGREGATE cs_sum(int4)
|
||||
(
|
||||
SFUNC = int4_sum(int8, int4),
|
||||
STYPE = int8,
|
||||
INITCOND = '0'
|
||||
)
|
||||
CREATE COLLATION cs_builtin_c ( PROVIDER = builtin, LOCALE = "C" )
|
||||
CREATE DOMAIN cs_positive AS integer CHECK (VALUE > 0)
|
||||
CREATE FUNCTION cs_add(int4, int4) returns int4 language sql
|
||||
as 'select $1 + $2'
|
||||
CREATE OPERATOR + (function = cs_add, leftarg = int4, rightarg = int4)
|
||||
CREATE PROCEDURE cs_proc(int4, int4)
|
||||
BEGIN ATOMIC
|
||||
SELECT cs_add($1,$2);
|
||||
END
|
||||
-- this checks that psql is not fooled by an irrelevant BEGIN
|
||||
CREATE VIEW begin AS SELECT 1 AS one
|
||||
CREATE TEXT SEARCH CONFIGURATION cs_ts_conf (copy=english)
|
||||
CREATE TEXT SEARCH DICTIONARY cs_ts_dict (template=simple)
|
||||
CREATE TEXT SEARCH PARSER cs_ts_prs
|
||||
(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end,
|
||||
lextypes = prsd_lextype)
|
||||
CREATE TEXT SEARCH TEMPLATE cs_ts_temp (lexize=dsimple_lexize)
|
||||
CREATE TYPE regress_schema_misc.cs_enum AS ENUM ('red', 'orange')
|
||||
CREATE TYPE cs_composite AS (a int, b float8)
|
||||
CREATE TYPE cs_range AS RANGE (subtype = float8, subtype_diff = float8mi)
|
||||
-- demonstrate creation of a base type with its I/O functions
|
||||
CREATE TYPE cs_type
|
||||
CREATE FUNCTION cs_type_in(cstring)
|
||||
RETURNS cs_type LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT
|
||||
AS 'int4in'
|
||||
CREATE FUNCTION cs_type_out(cs_type)
|
||||
RETURNS cstring LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT
|
||||
AS 'int4out'
|
||||
CREATE TYPE cs_type (
|
||||
INPUT = cs_type_in,
|
||||
OUTPUT = cs_type_out,
|
||||
LIKE = int4
|
||||
)
|
||||
GRANT USAGE ON TYPE cs_type TO public
|
||||
;
|
||||
NOTICE: return type cs_type is only a shell
|
||||
NOTICE: argument type cs_type is only a shell
|
||||
LINE 33: CREATE FUNCTION cs_type_out(cs_type)
|
||||
^
|
||||
\df regress_schema_misc.cs_add
|
||||
List of functions
|
||||
Schema | Name | Result data type | Argument data types | Type
|
||||
---------------------+--------+------------------+---------------------+------
|
||||
regress_schema_misc | cs_add | integer | integer, integer | func
|
||||
(1 row)
|
||||
|
||||
\df regress_schema_misc.cs_proc
|
||||
List of functions
|
||||
Schema | Name | Result data type | Argument data types | Type
|
||||
---------------------+---------+------------------+------------------------+------
|
||||
regress_schema_misc | cs_proc | | IN integer, IN integer | proc
|
||||
(1 row)
|
||||
|
||||
\da regress_schema_misc.cs_sum
|
||||
List of aggregate functions
|
||||
Schema | Name | Result data type | Argument data types | Description
|
||||
---------------------+--------+------------------+---------------------+-------------
|
||||
regress_schema_misc | cs_sum | bigint | integer |
|
||||
(1 row)
|
||||
|
||||
\do regress_schema_misc.+
|
||||
List of operators
|
||||
Schema | Name | Left arg type | Right arg type | Result type | Description
|
||||
---------------------+------+---------------+----------------+-------------+-------------
|
||||
regress_schema_misc | + | integer | integer | integer |
|
||||
(1 row)
|
||||
|
||||
\dO regress_schema_misc.*
|
||||
List of collations
|
||||
Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
|
||||
---------------------+--------------+----------+---------+-------+--------+-----------+----------------
|
||||
regress_schema_misc | cs_builtin_c | builtin | | | C | | yes
|
||||
(1 row)
|
||||
|
||||
\dT regress_schema_misc.*
|
||||
List of data types
|
||||
Schema | Name | Description
|
||||
---------------------+-----------------------------------+-------------
|
||||
regress_schema_misc | regress_schema_misc.cs_composite |
|
||||
regress_schema_misc | regress_schema_misc.cs_enum |
|
||||
regress_schema_misc | regress_schema_misc.cs_multirange |
|
||||
regress_schema_misc | regress_schema_misc.cs_positive |
|
||||
regress_schema_misc | regress_schema_misc.cs_range |
|
||||
regress_schema_misc | regress_schema_misc.cs_type |
|
||||
(6 rows)
|
||||
|
||||
\dF regress_schema_misc.*
|
||||
List of text search configurations
|
||||
Schema | Name | Description
|
||||
---------------------+------------+-------------
|
||||
regress_schema_misc | cs_ts_conf |
|
||||
(1 row)
|
||||
|
||||
\dFd regress_schema_misc.*
|
||||
List of text search dictionaries
|
||||
Schema | Name | Description
|
||||
---------------------+------------+-------------
|
||||
regress_schema_misc | cs_ts_dict |
|
||||
(1 row)
|
||||
|
||||
\dFp regress_schema_misc.*
|
||||
List of text search parsers
|
||||
Schema | Name | Description
|
||||
---------------------+-----------+-------------
|
||||
regress_schema_misc | cs_ts_prs |
|
||||
(1 row)
|
||||
|
||||
\dFt regress_schema_misc.*
|
||||
List of text search templates
|
||||
Schema | Name | Description
|
||||
---------------------+------------+-------------
|
||||
regress_schema_misc | cs_ts_temp |
|
||||
(1 row)
|
||||
|
||||
DROP SCHEMA regress_schema_misc CASCADE;
|
||||
NOTICE: drop cascades to 17 other objects
|
||||
DETAIL: drop cascades to function regress_schema_misc.cs_sum(integer)
|
||||
drop cascades to collation regress_schema_misc.cs_builtin_c
|
||||
drop cascades to type regress_schema_misc.cs_positive
|
||||
drop cascades to function regress_schema_misc.cs_add(integer,integer)
|
||||
drop cascades to operator regress_schema_misc.+(integer,integer)
|
||||
drop cascades to function regress_schema_misc.cs_proc(integer,integer)
|
||||
drop cascades to view regress_schema_misc.begin
|
||||
drop cascades to text search configuration regress_schema_misc.cs_ts_conf
|
||||
drop cascades to text search dictionary regress_schema_misc.cs_ts_dict
|
||||
drop cascades to text search parser regress_schema_misc.cs_ts_prs
|
||||
drop cascades to text search template regress_schema_misc.cs_ts_temp
|
||||
drop cascades to type regress_schema_misc.cs_enum
|
||||
drop cascades to type regress_schema_misc.cs_composite
|
||||
drop cascades to type regress_schema_misc.cs_range
|
||||
drop cascades to function regress_schema_misc.cs_type_out(regress_schema_misc.cs_type)
|
||||
drop cascades to type regress_schema_misc.cs_type
|
||||
drop cascades to function regress_schema_misc.cs_type_in(cstring)
|
||||
-- Clean up
|
||||
DROP ROLE regress_create_schema_role;
|
||||
|
||||
@@ -8,7 +8,7 @@ CREATE ROLE regress_create_schema_role SUPERUSER;
|
||||
|
||||
-- Cases where schema creation fails as objects are qualified with a schema
|
||||
-- that does not match with what's expected.
|
||||
-- This checks most object types that include schema qualifications.
|
||||
-- This checks all the object types that include schema qualifications.
|
||||
CREATE SCHEMA AUTHORIZATION regress_create_schema_role
|
||||
CREATE SEQUENCE schema_not_existing.seq;
|
||||
CREATE SCHEMA AUTHORIZATION regress_create_schema_role
|
||||
@@ -20,9 +20,6 @@ CREATE SCHEMA AUTHORIZATION regress_create_schema_role
|
||||
CREATE SCHEMA AUTHORIZATION regress_create_schema_role
|
||||
CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_existing.tab
|
||||
EXECUTE FUNCTION schema_trig.no_func();
|
||||
CREATE SCHEMA AUTHORIZATION regress_create_schema_role
|
||||
CREATE FUNCTION schema_not_existing.func(int) RETURNS int
|
||||
AS 'SELECT $1' LANGUAGE sql;
|
||||
-- Again, with a role specification and no schema names.
|
||||
SET ROLE regress_create_schema_role;
|
||||
CREATE SCHEMA AUTHORIZATION CURRENT_ROLE
|
||||
@@ -101,81 +98,5 @@ CREATE SCHEMA regress_schema_fk
|
||||
|
||||
DROP SCHEMA regress_schema_fk CASCADE;
|
||||
|
||||
-- Test miscellaneous object types within CREATE SCHEMA.
|
||||
CREATE SCHEMA regress_schema_misc
|
||||
CREATE AGGREGATE cs_sum(int4)
|
||||
(
|
||||
SFUNC = int4_sum(int8, int4),
|
||||
STYPE = int8,
|
||||
INITCOND = '0'
|
||||
)
|
||||
|
||||
CREATE COLLATION cs_builtin_c ( PROVIDER = builtin, LOCALE = "C" )
|
||||
|
||||
CREATE DOMAIN cs_positive AS integer CHECK (VALUE > 0)
|
||||
|
||||
CREATE FUNCTION cs_add(int4, int4) returns int4 language sql
|
||||
as 'select $1 + $2'
|
||||
|
||||
CREATE OPERATOR + (function = cs_add, leftarg = int4, rightarg = int4)
|
||||
|
||||
CREATE PROCEDURE cs_proc(int4, int4)
|
||||
BEGIN ATOMIC
|
||||
SELECT cs_add($1,$2);
|
||||
END
|
||||
|
||||
-- this checks that psql is not fooled by an irrelevant BEGIN
|
||||
CREATE VIEW begin AS SELECT 1 AS one
|
||||
|
||||
CREATE TEXT SEARCH CONFIGURATION cs_ts_conf (copy=english)
|
||||
|
||||
CREATE TEXT SEARCH DICTIONARY cs_ts_dict (template=simple)
|
||||
|
||||
CREATE TEXT SEARCH PARSER cs_ts_prs
|
||||
(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end,
|
||||
lextypes = prsd_lextype)
|
||||
|
||||
CREATE TEXT SEARCH TEMPLATE cs_ts_temp (lexize=dsimple_lexize)
|
||||
|
||||
CREATE TYPE regress_schema_misc.cs_enum AS ENUM ('red', 'orange')
|
||||
|
||||
CREATE TYPE cs_composite AS (a int, b float8)
|
||||
|
||||
CREATE TYPE cs_range AS RANGE (subtype = float8, subtype_diff = float8mi)
|
||||
|
||||
-- demonstrate creation of a base type with its I/O functions
|
||||
|
||||
CREATE TYPE cs_type
|
||||
|
||||
CREATE FUNCTION cs_type_in(cstring)
|
||||
RETURNS cs_type LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT
|
||||
AS 'int4in'
|
||||
|
||||
CREATE FUNCTION cs_type_out(cs_type)
|
||||
RETURNS cstring LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT
|
||||
AS 'int4out'
|
||||
|
||||
CREATE TYPE cs_type (
|
||||
INPUT = cs_type_in,
|
||||
OUTPUT = cs_type_out,
|
||||
LIKE = int4
|
||||
)
|
||||
|
||||
GRANT USAGE ON TYPE cs_type TO public
|
||||
;
|
||||
|
||||
\df regress_schema_misc.cs_add
|
||||
\df regress_schema_misc.cs_proc
|
||||
\da regress_schema_misc.cs_sum
|
||||
\do regress_schema_misc.+
|
||||
\dO regress_schema_misc.*
|
||||
\dT regress_schema_misc.*
|
||||
\dF regress_schema_misc.*
|
||||
\dFd regress_schema_misc.*
|
||||
\dFp regress_schema_misc.*
|
||||
\dFt regress_schema_misc.*
|
||||
|
||||
DROP SCHEMA regress_schema_misc CASCADE;
|
||||
|
||||
-- Clean up
|
||||
DROP ROLE regress_create_schema_role;
|
||||
|
||||
Reference in New Issue
Block a user