Compare commits

..

No commits in common. "b7e8f27d1478f75a443a4df226f696b8c29e5107" and "5f6ec27a64774b10ff8522bc745e5e993503011d" have entirely different histories.

7 changed files with 16 additions and 181 deletions

View File

@ -107,7 +107,6 @@ do { \
static IndexScanDesc index_beginscan_internal(Relation indexRelation,
int nkeys, int norderbys, Snapshot snapshot,
ParallelIndexScanDesc pscan, bool temp_snap);
static inline void validate_relation_kind(Relation r);
/* ----------------------------------------------------------------
@ -136,30 +135,12 @@ index_open(Oid relationId, LOCKMODE lockmode)
r = relation_open(relationId, lockmode);
validate_relation_kind(r);
return r;
}
/* ----------------
* try_index_open - open a index relation by relation OID
*
* Same as index_open, except return NULL instead of failing
* if the relation does not exist.
* ----------------
*/
Relation
try_index_open(Oid relationId, LOCKMODE lockmode)
{
Relation r;
r = try_relation_open(relationId, lockmode);
/* leave if index does not exist */
if (!r)
return NULL;
validate_relation_kind(r);
if (r->rd_rel->relkind != RELKIND_INDEX &&
r->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not an index",
RelationGetRelationName(r))));
return r;
}
@ -187,24 +168,6 @@ index_close(Relation relation, LOCKMODE lockmode)
UnlockRelationId(&relid, lockmode);
}
/* ----------------
* validate_relation_kind - check the relation's kind
*
* Make sure relkind is an index or a partitioned index.
* ----------------
*/
static inline void
validate_relation_kind(Relation r)
{
if (r->rd_rel->relkind != RELKIND_INDEX &&
r->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not an index",
RelationGetRelationName(r))));
}
/* ----------------
* index_insert - insert an index tuple into a relation
* ----------------

View File

@ -3612,24 +3612,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
* Open the target index relation and get an exclusive lock on it, to
* ensure that no one else is touching this particular index.
*/
if ((params->options & REINDEXOPT_MISSING_OK) != 0)
iRel = try_index_open(indexId, AccessExclusiveLock);
else
iRel = index_open(indexId, AccessExclusiveLock);
/* if index relation is gone, leave */
if (!iRel)
{
/* Roll back any GUC changes */
AtEOXact_GUC(false, save_nestlevel);
/* Restore userid and security context */
SetUserIdAndSecContext(save_userid, save_sec_context);
/* Close parent heap relation, but keep locks */
table_close(heapRelation, NoLock);
return;
}
iRel = index_open(indexId, AccessExclusiveLock);
if (progress)
pgstat_progress_update_param(PROGRESS_CREATEIDX_ACCESS_METHOD_OID,

View File

@ -138,7 +138,6 @@ typedef struct IndexOrderByDistance
#define IndexScanIsValid(scan) PointerIsValid(scan)
extern Relation index_open(Oid relationId, LOCKMODE lockmode);
extern Relation try_index_open(Oid relationId, LOCKMODE lockmode);
extern void index_close(Relation relation, LOCKMODE lockmode);
extern bool index_insert(Relation indexRelation,

View File

@ -32,9 +32,8 @@ DATA = plpgsql.control plpgsql--1.0.sql
REGRESS_OPTS = --dbname=$(PL_TESTDB)
REGRESS = plpgsql_array plpgsql_cache plpgsql_call plpgsql_control \
plpgsql_copy plpgsql_domain plpgsql_misc \
plpgsql_record plpgsql_simple plpgsql_transaction \
REGRESS = plpgsql_array plpgsql_call plpgsql_control plpgsql_copy plpgsql_domain \
plpgsql_record plpgsql_cache plpgsql_simple plpgsql_transaction \
plpgsql_trap plpgsql_trigger plpgsql_varprops
# where to find gen_keywordlist.pl and subsidiary files

View File

@ -1,31 +0,0 @@
--
-- Miscellaneous topics
--
-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE
do
$$
declare procedure int; -- check we still recognize non-keywords as vars
begin
create function test1() returns int
begin atomic
select 2 + 2;
end;
create or replace procedure test2(x int)
begin atomic
select x + 2;
end;
end
$$;
\sf test1
CREATE OR REPLACE FUNCTION public.test1()
RETURNS integer
LANGUAGE sql
BEGIN ATOMIC
SELECT (2 + 2);
END
\sf test2
CREATE OR REPLACE PROCEDURE public.test2(IN x integer)
LANGUAGE sql
BEGIN ATOMIC
SELECT (x + 2);
END

View File

@ -79,8 +79,7 @@ static PLpgSQL_expr *read_sql_expression2(int until, int until2,
int *endtoken);
static PLpgSQL_expr *read_sql_stmt(void);
static PLpgSQL_type *read_datatype(int tok);
static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location,
PLword *word);
static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location);
static PLpgSQL_stmt_fetch *read_fetch_direction(void);
static void complete_direction(PLpgSQL_stmt_fetch *fetch,
bool *check_FROM);
@ -1995,11 +1994,11 @@ loop_body : proc_sect K_END K_LOOP opt_label ';'
*/
stmt_execsql : K_IMPORT
{
$$ = make_execsql_stmt(K_IMPORT, @1, NULL);
$$ = make_execsql_stmt(K_IMPORT, @1);
}
| K_INSERT
{
$$ = make_execsql_stmt(K_INSERT, @1, NULL);
$$ = make_execsql_stmt(K_INSERT, @1);
}
| T_WORD
{
@ -2010,7 +2009,7 @@ stmt_execsql : K_IMPORT
if (tok == '=' || tok == COLON_EQUALS ||
tok == '[' || tok == '.')
word_is_not_variable(&($1), @1);
$$ = make_execsql_stmt(T_WORD, @1, &($1));
$$ = make_execsql_stmt(T_WORD, @1);
}
| T_CWORD
{
@ -2021,7 +2020,7 @@ stmt_execsql : K_IMPORT
if (tok == '=' || tok == COLON_EQUALS ||
tok == '[' || tok == '.')
cword_is_not_variable(&($1), @1);
$$ = make_execsql_stmt(T_CWORD, @1, NULL);
$$ = make_execsql_stmt(T_CWORD, @1);
}
;
@ -2937,13 +2936,8 @@ read_datatype(int tok)
return result;
}
/*
* Read a generic SQL statement. We have already read its first token;
* firsttoken is that token's code and location its starting location.
* If firsttoken == T_WORD, pass its yylval value as "word", else pass NULL.
*/
static PLpgSQL_stmt *
make_execsql_stmt(int firsttoken, int location, PLword *word)
make_execsql_stmt(int firsttoken, int location)
{
StringInfoData ds;
IdentifierLookup save_IdentifierLookup;
@ -2956,16 +2950,9 @@ make_execsql_stmt(int firsttoken, int location, PLword *word)
bool have_strict = false;
int into_start_loc = -1;
int into_end_loc = -1;
int paren_depth = 0;
int begin_depth = 0;
bool in_routine_definition = false;
int token_count = 0;
char tokens[4]; /* records the first few tokens */
initStringInfo(&ds);
memset(tokens, 0, sizeof(tokens));
/* special lookup mode for identifiers within the SQL text */
save_IdentifierLookup = plpgsql_IdentifierLookup;
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
@ -2974,12 +2961,6 @@ make_execsql_stmt(int firsttoken, int location, PLword *word)
* Scan to the end of the SQL command. Identify any INTO-variables
* clause lurking within it, and parse that via read_into_target().
*
* The end of the statement is defined by a semicolon ... except that
* semicolons within parentheses or BEGIN/END blocks don't terminate a
* statement. We follow psql's lead in not recognizing BEGIN/END except
* after CREATE [OR REPLACE] {FUNCTION|PROCEDURE}. END can also appear
* within a CASE construct, so we treat CASE/END like BEGIN/END.
*
* Because INTO is sometimes used in the main SQL grammar, we have to be
* careful not to take any such usage of INTO as a PL/pgSQL INTO clause.
* There are currently three such cases:
@ -3005,50 +2986,13 @@ make_execsql_stmt(int firsttoken, int location, PLword *word)
* break this logic again ... beware!
*/
tok = firsttoken;
if (tok == T_WORD && strcmp(word->ident, "create") == 0)
tokens[token_count] = 'c';
token_count++;
for (;;)
{
prev_tok = tok;
tok = yylex();
if (have_into && into_end_loc < 0)
into_end_loc = yylloc; /* token after the INTO part */
/* Detect CREATE [OR REPLACE] {FUNCTION|PROCEDURE} */
if (tokens[0] == 'c' && token_count < sizeof(tokens))
{
if (tok == K_OR)
tokens[token_count] = 'o';
else if (tok == T_WORD &&
strcmp(yylval.word.ident, "replace") == 0)
tokens[token_count] = 'r';
else if (tok == T_WORD &&
strcmp(yylval.word.ident, "function") == 0)
tokens[token_count] = 'f';
else if (tok == T_WORD &&
strcmp(yylval.word.ident, "procedure") == 0)
tokens[token_count] = 'f'; /* treat same as "function" */
if (tokens[1] == 'f' ||
(tokens[1] == 'o' && tokens[2] == 'r' && tokens[3] == 'f'))
in_routine_definition = true;
token_count++;
}
/* Track paren nesting (needed for CREATE RULE syntax) */
if (tok == '(')
paren_depth++;
else if (tok == ')' && paren_depth > 0)
paren_depth--;
/* We need track BEGIN/END nesting only in a routine definition */
if (in_routine_definition && paren_depth == 0)
{
if (tok == K_BEGIN || tok == K_CASE)
begin_depth++;
else if (tok == K_END && begin_depth > 0)
begin_depth--;
}
/* Command-ending semicolon? */
if (tok == ';' && paren_depth == 0 && begin_depth == 0)
if (tok == ';')
break;
if (tok == 0)
yyerror("unexpected end of function definition");

View File

@ -1,22 +0,0 @@
--
-- Miscellaneous topics
--
-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE
do
$$
declare procedure int; -- check we still recognize non-keywords as vars
begin
create function test1() returns int
begin atomic
select 2 + 2;
end;
create or replace procedure test2(x int)
begin atomic
select x + 2;
end;
end
$$;
\sf test1
\sf test2