Skip to content

Disable foreign distributed tables - #5605

Merged
Ahmet Gedemenli (agedemenli) merged 12 commits into
masterfrom
disable-foreign-distributed-tables
Jan 7, 2022
Merged

Disable foreign distributed tables#5605
Ahmet Gedemenli (agedemenli) merged 12 commits into
masterfrom
disable-foreign-distributed-tables

Conversation

@agedemenli

@agedemenli Ahmet Gedemenli (agedemenli) commented Jan 7, 2022

Copy link
Copy Markdown
Contributor

DESCRIPTION: Disables distributed&reference foreign tables

Disables create_distributed_table and create_reference_table for foreign tables. Foreign tables can now only be added to metadata. Errors out when trying to distribute foreign tables.

We don't want to break users that have distributed&reference foreign tables already. With this PR, we log a WARNING message for them, when they use an existing distributed foreign table. This check is done in distributed planner.

Includes a lot of changes in regression test output, for the existing distributed foreign table test.
Added some test to show the error when trying to distribute a foreign table.
Can't add regression test for the warning, as it's not a case we can see for now. The warning is only for the users that have distributed foreign tables already.

fixes: #5604

@codecov

codecov Bot commented Jan 7, 2022

Copy link
Copy Markdown

Codecov Report

Merging #5605 (0ed8226) into master (9d858cb) will decrease coverage by 1.81%.
The diff coverage is 88.46%.

@@            Coverage Diff             @@
##           master    #5605      +/-   ##
==========================================
- Coverage   92.66%   90.85%   -1.82%     
==========================================
  Files         219      219              
  Lines       46011    46034      +23     
==========================================
- Hits        42637    41825     -812     
- Misses       3374     4209     +835     

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the question Marco Slot (@marcocitus) had earlier was that what about existing foreign distributed tables that were created on 10.2 or earlier.

Can you still (a) query those (b) run alter/rename/DDLs etc (c) drop them

Also, when you do (a) and (b), should we warn users?

@onderkalaci

Copy link
Copy Markdown
Contributor

Also, when you do (a) and (b), should we warn users?

Well, that might be too much. Maybe warn once per session or such on these occasions.

@agedemenli

Copy link
Copy Markdown
Contributor Author

I think the question Marco Slot (@marcocitus) had earlier was that what about existing foreign distributed tables that were created on 10.2 or earlier.

Can you still (a) query those (b) run alter/rename/DDLs etc (c) drop them

Also, when you do (a) and (b), should we warn users?

Yes, all of them are still allowed. I'll add a warning for such cases.

IsCitusTable(relationId) && !IsCitusTableType(relationId, CITUS_LOCAL_TABLE))
{
DistributedForeignTableWarningPrompted = true;
ereport(WARNING, (errmsg("support for distributed foreign tables are deprecated"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

support for distributed or reference foreign tables are deprecated, please use Citus managed local tables
(keep the detail)

return NIL;
}

WarnUnsupportedIfForeignDistributedTable(leftRelationId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's only keep WarnUnsupportedIfForeignDistributedTable in distributed planner. These DDL hooks seems excessive. If you have a distributed foreign table, you'd most likely run a query compared to any DDL.


if (IsCitusTable(rangeTableEntry->relid))
{
WarnUnsupportedIfForeignDistributedTable(rangeTableEntry->relid);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really not convinced that calling WarnUnsupportedIfForeignDistributedTable inside ListContainsDistributedTableRTE is a good approach.

What about:

	else if (CitusHasBeenLoaded())
	{
		needsDistributedPlanning = ListContainsDistributedTableRTE(rangeTableList, maybeHasForeignTable);
		if (needsDistributedPlanning)
		{
			fastPathRouterQuery = FastPathRouterQuery(parse, &distributionKeyValue);
			
			if (maybeHasForeignTable)
			{
			
                 WarnUnsupportedIfForeignDistributedTable(rangeTableEntry->relid);
			}
		
		}
	}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually need a relationId to pass to WarnUnsupportedIfForeignDistributedTable, to verify the relation is a distributed foreign table. But here we don't have a relationId, instead we have a list that might contain a relation that is a distributed foreign table.

Besides, there is one more place that we call ListContainsDistributedTableRTE, that has nothing to do with foreign tables, so passing such a parameter doesn't make sense in that place.

We can consider iterating the list once more, to find out if it contains any distributed foreign table; but this option adds some unnecessary complexity. Maybe we can avoid this complexity by doing the iteration only when the variable DistributedForeignTableWarningPrompted is false ?

Something like:

	else if (CitusHasBeenLoaded())
	{
		needsDistributedPlanning = ListContainsDistributedTableRTE(rangeTableList);
		if (needsDistributedPlanning)
		{
			fastPathRouterQuery = FastPathRouterQuery(parse, &distributionKeyValue);

			WarnIfListHasForeignDistributedTable(rangeTableList);
		}
	}

and

static void
WarnIfListHasForeignDistributedTable(List *rangeTableList)
{
	RangeTblEntry *rangeTableEntry = NULL;
	foreach_ptr(rangeTableEntry, rangeTableList)
	{
		if (DistributedForeignTableWarningPrompted)
		{
			return;
		}

		WarnUnsupportedIfForeignDistributedTable(rangeTableEntry->relid);
	}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides, there is one more place that we call ListContainsDistributedTableRTE, that has nothing to do with foreign tables, so passing such a parameter doesn't make sense in that place.

Similarly, calling WarnUnsupportedIfForeignDistributedTable doesn't make sense :)

Can't we re-iterate the list only when we know there is a foreign table? In majority of the cases DistributedForeignTableWarningPrompted will be false, hence we'd re-iterate unnecessarily with the above suggestion

@agedemenli
Ahmet Gedemenli (agedemenli) force-pushed the disable-foreign-distributed-tables branch from c0f1b37 to 1d99531 Compare January 7, 2022 14:05
* We do that because now we only support Citus Local Tables for foreign tables.
*/
void
WarnUnsupportedIfForeignDistributedTable(Oid relationId)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need this function now? Can't we inline into WarnIfListHasForeignDistributedTable? It seems confusing to have an external function with this name.

And, when we do that, we should probably be able to remove DistributedForeignTableWarningPrompted check from this part?

Comment thread src/backend/distributed/commands/table.c Outdated
Comment thread src/backend/distributed/planner/distributed_planner.c

return ListContainsDistributedTableRTE(allRTEs);
/* redundant parameter for here */
bool *maybeHasForeignDistributedTable = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: can't we pass NULL? See my other comment as well

return ListContainsDistributedTableRTE(allRTEs, NULL);

* We do that because now we only support Citus Local Tables for foreign tables.
*/
void
WarnIfListHasForeignDistributedTable(List *rangeTableList)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: probably better to move where it is used, and make it a static function

RangeTblEntry *rangeTableEntry = NULL;
foreach_ptr(rangeTableEntry, rangeTableList)
{
if (DistributedForeignTableWarningPrompted)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: might be good to move this check out of the loop

@agedemenli
Ahmet Gedemenli (agedemenli) deleted the disable-foreign-distributed-tables branch January 7, 2022 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Disable creating distributed&reference tables from foreign tables

2 participants