Project: YugabyteDB (App Definition and Development / Database)
File: func_yb_is_local_table.md

title: ybislocal_table() function [YSQL] headerTitle: ybislocal_table(oid) linkTitle: ybislocal_table() description: Returns whether the given 'oid' is a table replicated only in the local region. menu: v2.18: identifier: api-ysql-exprs-ybislocal_table parent: geo-partitioning-helper-functions type: docs `ybislocal_table` indicates whether a table is pinned to the local region. The function takes a table's OID (object identifier), and looks for a tablespace associated with that table. If the tablespace is confined to the same region as that of the YugabyteDB node processing the query, the function returns `true`. Otherwise, the function returns `false`. {{< note title="Note" >}} Passing the OID of a temporary table will always return true as temporary tables are considered local. Tables not assigned a tablespace will always be considered remote. {{< /note >}} This function is primarily helpful while implementing , as it can significantly simplify selecting rows from the local partition. Every table contains a system column called `tableoid`. This stores the `oid` of the table to which the row belongs. While querying a partitioned table, the `tableoid` column thus returns the `oid` of the partition to which the row belongs. The following sections describe how the `tableoid` column can be used with `ybislocal_table` function to query the local partition. You can create a 3 node multi-region cluster and a geo-partitioned table using tablespaces with the following steps: Create a cluster spread across 3 regions us-west-1, us-east-1, us-east-2 using yugabyted as follows: ```sh ./bin/yugabyted start \ --base_dir=/home/yugabyte/<IP1>/yugabyte-data \ --listen=<IP1> \ --masterflags "placementcloud=aws,placementregion=us-west-1,placementzone=us-west-1c" \ --tserverflags "placementcloud=aws,placementregion=us-west-1,placementzone=us-west-1c" ./bin/yugabyted start \ --base_dir=/home/yugabyte/<IP2>/yugabyte-data \ --listen=<IP2> \ --join=<IP1> \ --masterflags "placementcloud=aws,placementregion=us-east-2,placementzone=us-east-2c" \ --tserverflags "placementcloud=aws,placementregion=us-east-2,placementzone=us-east-2c" ./bin/yugabyted start \ --base_dir=/home/yugabyte/<IP3>/yugabyte-data \ --listen=<IP3> \ --join=<IP1> \ --masterflags "placementcloud=aws,placementregion=us-east-1,placementzone=us-east-1a" \ --tserverflags "placementcloud=aws,placementregion=us-east-1,placementzone=us-east-1a" ``` Use to specify the placement configuration to be used by the cluster as follows: ```sh ./bin/yb-admin -masteraddresses <IP1>:7100 modifyplacement_info aws.us-west-1.us-west-1c:1,aws.us-east-1.us-east-1a:1,aws.us-east-2.us-east-2c:1 3 ``` Create tablespaces corresponding to the regions used by the cluster created above as follows: ```sql CREATE TABLESPACE uswesttablespace WITH (replicaplacement=' {"numreplicas":1,"placementblocks":[ {"cloud":"aws","region":"us-west-1","zone":"us-west-1c","minnum_replicas":1}]}'); CREATE TABLESPACE useast1tablespace WITH (replicaplacement=' {"numreplicas":1,"placementblocks":[ {"cloud":"aws","region":"us-east-1","zone":"us-east-1a","minnum_replicas":1}]}'); CREATE TABLESPACE useast2tablespace WITH (replicaplacement=' {"numreplicas":1,"placementblocks":[ {"cloud":"aws","region":"us-east-2","zone":"us-east-2c","minnum_replicas":1}]}'); ``` For more information on how to set up a cluster with or with corresponding tablespaces, see . Using the tablespaces, you can create a geo-partitioned table as follows. This is a partitioned table with 3 partitions, where each partition is pinned to a different

```sql CREATE TABLE users(user_id INTEGER NOT NULL, user_info VARCHAR NOT NULL, geo_partition VARCHAR NOT NULL, PRIMARY KEY(userid, geopartition)) PARTITION BY LIST(geo_partition); CREATE TABLE useruswest PARTITION OF users FOR VALUES IN ('us-west') TABLESPACE uswesttablespace; CREATE TABLE useruseast1 PARTITION OF users FOR VALUES IN ('us-east1') TABLESPACE useast1tablespace; CREATE TABLE useruseast2 PARTITION OF users FOR VALUES IN ('us-east2') TABLESPACE useast2tablespace; ``` Insert some sample data to the `users` table as follows: ```sql INSERT INTO users VALUES(1, 'US east user', 'us-east1'); INSERT INTO users VALUES(2, 'US west user', 'us-west'); INSERT INTO users VALUES(3, 'US central user', 'us-east2'); ``` In a partitioned setup, if there are no `WHERE` clause restrictions on the partition key, note that every query on a partitioned table gets fanned out to all of its child partitions: ```sql EXPLAIN (COSTS OFF) SELECT * FROM users; ``` ```output QUERY PLAN Append -> Seq Scan on useruseast2 -> Seq Scan on useruseast1 -> Seq Scan on useruswest (4 rows) ``` Assuming that the client is in the `us-west` region, note that using `ybislocaltable()` in the `WHERE` clause causes YSQL to only scan the `ususer_west` table: ```sql EXPLAIN (COSTS OFF) SELECT * FROM users WHERE ybislocal_table(tableoid); ``` ```output QUERY PLAN Append -> Seq Scan on useruswest Filter: ybislocal_table(tableoid) (3 rows) ``` ```sql SELECT * FROM users WHERE ybislocal_table(tableoid); ``` ```output SELECT * FROM users WHERE ybislocal_table(tableoid); userid | userinfo | geo_partition +--+ 2 | US west user | us-west (1 row) ``` The `ybislocal_table` function can also be used while performing JOINs, to filter out results. Assume another partitioned table `users_transactions` and some sample data as follows: ```sql CREATE TABLE userstransactions (userid INTEGER NOT NULL, transaction_id INTEGER NOT NULL, geo_partition VARCHAR NOT NULL) PARTITION BY LIST(geo_partition); -- Create 3 partitions for each tablespace. CREATE TABLE usertxnwest PARTITION OF userstransactions FOR VALUES IN ('us-west') TABLESPACE uswest_tablespace; CREATE TABLE usertxneast1 PARTITION OF userstransactions FOR VALUES IN ('us-east1') TABLESPACE useast1_tablespace; CREATE TABLE usertxneast2 PARTITION OF userstransactions FOR VALUES IN ('us-east2') TABLESPACE useast2_tablespace; -- Insert a row into each partition. INSERT INTO users_transactions VALUES(1, 3789, 'us-east1'); INSERT INTO users_transactions VALUES(2, 5276, 'us-west'); INSERT INTO users_transactions VALUES(3, 2984, 'us-east2'); ``` To perform a `JOIN` across the local partitions of both the tables, you can run the following query with two `WHERE` clauses, one for each partitioned table. ```sql SELECT * FROM users, userstransactions WHERE users.userid = userstransactions.userid AND ybislocaltable(users.tableoid) AND ybislocaltable(users_transactions.tableoid); ``` ```output userid | userinfo | geopartition | userid | transactionid | geopartition +--+++-+ 2 | US west user | us-west | 2 | 5276 | us-west (1 row) ``` Note that only the local partition in both the partitioned tables is being scanned. ```sql EXPLAIN (COSTS OFF) SELECT * FROM users, userstransactions WHERE users.userid = userstransactions.userid AND ybislocaltable(users.tableoid) AND ybislocaltable(users_transactions.tableoid); ``` ```output QUERY PLAN -- Merge Join Merge Cond: (useruswest.userid = usertxnwest.userid) -> Sort Sort Key: useruswest.user_id -> Append -> Seq Scan on useruswest Filter: ybislocal_table(tableoid) -> Sort Sort Key: usertxnwest.user_id -> Append -> Seq Scan on usertxnwest Filter: ybislocal_table(tableoid) (12 rows) ``` The `ybislocal_table` function can be used on any database object that can be associated with a tablespace. For instance, the following query can be used to list all the indexes and tables that have been tied to a local tablespace: ```sql SELECT oid, relname from pgclass WHERE ybislocaltable(oid); ``` ```output oid | relname -+- 16392 | useruswest 16395 | useruswest_pkey 16410 | usertxnwest (3 rows) ``` Usage of this function is not optimized for `UPDATE` and `DELETE` queries. The planner will still scan all the partitions to find the rows that are present in the local partition. Usage of this function is not optimized