Skip to content

Commit

Permalink
Support 'DROP INDEX table.index' and 'DROP INDEX ix ON schema.table' (b…
Browse files Browse the repository at this point in the history
…abelfish-for-postgresql#2216)

To support the syntax DROP INDEX table.index, the statement is rewritten in ANTLR as DROP INDEX index ON table, which is picked up by the backend parser.

To support the syntax DROP INDEX schema.table.index and DROP INDEX index ON schema.table, the statement is rewritten in ANTLR as DROP INDEX index ON table SCHEMA schema, which is picked up by the backend parser. Adding the SCHEMA clause for this case was necessary to avoid Bison reduce conflicts which resulted from seemingly more straightforward syntax options. 

In the backend parser, the trick is then to create an object reference in the DropStmt structure for the schema-qualified index with the schema name from the SCHEMA clause that was added, since PG's DROP INDEX only references the index, instead of its table like in T-SQL.

Also, proper error messages are now raised when attempting DROP INDEX with a 3-part of 4-part name.

Signed-off-by: Rob Verschoor [email protected]
Issues Resolved

BABEL-1483 Support DROP INDEX table.index syntax
BABEL-1652 Support DROP INDEX ix ON schema.table syntax
  • Loading branch information
robverschoor authored and ritanwar committed Jan 8, 2024
1 parent c0bdda9 commit b8e0ab9
Show file tree
Hide file tree
Showing 11 changed files with 977 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

%type <node> tsql_CreateFunctionStmt tsql_VariableSetStmt tsql_CreateTrigStmt tsql_TransactionStmt tsql_UpdateStmt tsql_DeleteStmt tsql_IndexStmt
%type <node> tsql_DropIndexStmt tsql_InsertStmt
%type <str> tsql_DropIndexStmtSchema
%type <node> tsql_CreateLoginStmt tsql_AlterLoginStmt tsql_DropLoginStmt
%type <node> tsql_CreateUserStmt tsql_DropRoleStmt tsql_AlterUserStmt
%type <node> tsql_CreateRoleStmt
Expand Down
31 changes: 27 additions & 4 deletions contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y
Original file line number Diff line number Diff line change
Expand Up @@ -1183,8 +1183,13 @@ DropStmt:
}
;

tsql_DropIndexStmtSchema:
SCHEMA name { $$ = $2; }
| /* EMPTY */ { $$ = NULL; }
;

tsql_DropIndexStmt:
DROP object_type_any_name name ON name_list
DROP object_type_any_name name ON name_list tsql_DropIndexStmtSchema
{
DropStmt *n = makeNode(DropStmt);
if(sql_dialect != SQL_DIALECT_TSQL)
Expand All @@ -1203,12 +1208,21 @@ tsql_DropIndexStmt:
}
n->removeType = $2;
n->missing_ok = false;
n->objects = list_make1(list_make1(makeString(construct_unique_index_name($3, makeRangeVarFromAnyName($5, @5, yyscanner)->relname))));
if ($6 != NULL)
{
/* SCHEMA clause present, use it to qualify the index name */
n->objects = list_make1(list_make2(makeString($6), makeString(construct_unique_index_name($3, makeRangeVarFromAnyName($5, @5, yyscanner)->relname))));
}
else
{
/* SCHEMA clause not present */
n->objects = list_make1(list_make1(makeString(construct_unique_index_name($3, makeRangeVarFromAnyName($5, @5, yyscanner)->relname))));
}
n->behavior = DROP_CASCADE;
n->concurrent = false;
$$ = (Node *)n;
}
| DROP object_type_any_name IF_P EXISTS name ON name_list
| DROP object_type_any_name IF_P EXISTS name ON name_list tsql_DropIndexStmtSchema
{
DropStmt *n = makeNode(DropStmt);
if(sql_dialect != SQL_DIALECT_TSQL)
Expand All @@ -1227,7 +1241,16 @@ tsql_DropIndexStmt:
}
n->removeType = $2;
n->missing_ok = true;
n->objects = list_make1(list_make1(makeString(construct_unique_index_name($5, makeRangeVarFromAnyName($7, @5, yyscanner)->relname))));
if ($8 != NULL)
{
/* SCHEMA clause present, use it to qualify the index name */
n->objects = list_make1(list_make2(makeString($8), makeString(construct_unique_index_name($5, makeRangeVarFromAnyName($7, @5, yyscanner)->relname))));
}
else
{
/* SCHEMA clause not present */
n->objects = list_make1(list_make1(makeString(construct_unique_index_name($5, makeRangeVarFromAnyName($7, @5, yyscanner)->relname))));
}
n->behavior = DROP_CASCADE;
n->concurrent = false;
$$ = (Node *)n;
Expand Down
33 changes: 33 additions & 0 deletions contrib/babelfishpg_tsql/src/tsqlIface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2408,6 +2408,39 @@ class tsqlBuilder : public tsqlCommonMutator
}
}

void exitDrop_relational_or_xml_or_spatial_index(TSqlParser::Drop_relational_or_xml_or_spatial_indexContext *ctx) override
{
/*
* Rewrite 'DROP INDEX index_name ON schema.table' as 'DROP INDEX index_name ON table SCHEMA schema'
* Note that using a 3-part or 4-part table name is not currently supported and has already been intercepted at this point.
*/
Assert(ctx->full_object_name());
if (ctx->full_object_name()->schema)
{
std::string str = getFullText(ctx->full_object_name());
size_t startPosition = ctx->full_object_name()->start->getStartIndex();
std::string tbName = getFullText(ctx->full_object_name()->object_name);
std::string schemaName = " SCHEMA " +getFullText(ctx->full_object_name()->schema);
rewritten_query_fragment.emplace(std::make_pair(startPosition, std::make_pair(str, tbName+schemaName)));
}
}

void exitDrop_backward_compatible_index(TSqlParser::Drop_backward_compatible_indexContext *ctx) override
{
/*
* Rewrite 'DROP INDEX [schema.]table.index_name' as 'DROP INDEX index_name ON table [ SCHEMA schema ]'
*/
std::string str = getFullText(ctx);
size_t startPosition = ctx->start->getStartIndex();
std::string ixName = getFullText(ctx->index_name);
std::string tbName = getFullText(ctx->table_or_view_name);
std::string schemaName = "";
if (ctx->owner_name) {
schemaName = " SCHEMA " +getFullText(ctx->owner_name);
}
rewritten_query_fragment.emplace(std::make_pair(startPosition, std::make_pair(str, ixName+" ON "+tbName+schemaName)));
}

//////////////////////////////////////////////////////////////////////////////
// Special handling of ITVF
//////////////////////////////////////////////////////////////////////////////
Expand Down
19 changes: 19 additions & 0 deletions contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,25 @@ antlrcpp::Any TsqlUnsupportedFeatureHandlerImpl::visitDdl_statement(TSqlParser::
{
handle(INSTR_UNSUPPORTED_TSQL_UNKNOWN_DDL, "ALTER FULLTEXT INDEX", getLineAndPos(ctx));
}
if (ctx->drop_index())
{
auto drop_index = ctx->drop_index();
if (drop_index->drop_relational_or_xml_or_spatial_index().size() > 0)
{
/* Raise proper error messages for the non-supported cases */
if (drop_index->drop_relational_or_xml_or_spatial_index(0)->full_object_name()->server)
{
/* DROP INDEX index_name ON srv.db.owner.table */
handle(INSTR_TSQL_DROP_INDEX, "DROP INDEX on remote table", getLineAndPos(ctx));
}
else if (drop_index->drop_relational_or_xml_or_spatial_index(0)->full_object_name()->database)
{
/* DROP INDEX index_name ON db.owner.table */
handle(INSTR_TSQL_DROP_INDEX, "DROP INDEX cross-database", getLineAndPos(ctx));
}
}
}

/*
* We have more than 100 DDLs but support a few of them.
* manage the whitelist here.
Expand Down
17 changes: 17 additions & 0 deletions test/JDBC/expected/drop_index-vu-cleanup.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use master
go
drop table guest.t1_drop_index
go
drop table dbo.t1_drop_index
go
drop procedure dbo.p1_drop_index
go
drop procedure dbo.p2_drop_index
go

use tempdb
go
drop table guest.t1_drop_index
go
drop table dbo.t1_drop_index
go
25 changes: 25 additions & 0 deletions test/JDBC/expected/drop_index-vu-prepare.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use master
go

create procedure p1_drop_index @p int=0
as
if @p = 0
drop index guest.t1_drop_index.ix1
else
drop index if exists guest.t1_drop_index.ix1
select db_name(), object_name(id), object_schema_name(id), name from sysindexes where name like 'ix1%' order by 1,2,3,4
go


create procedure p2_drop_index @p int=0
as
if @p = 0
drop index ix1 on guest.t1_drop_index
else
drop index if exists ix1 on guest.t1_drop_index
select db_name(), object_name(id), object_schema_name(id), name from sysindexes where name like 'ix1%' order by 1,2,3,4
go

use tempdb
go

Loading

0 comments on commit b8e0ab9

Please sign in to comment.