[jira] [Updated] (IGNITE-25369) Sql. Introduce EXPLAIN MAPPING FOR command

2025-05-19 Thread Konstantin Orlov (Jira)


 [ 
https://issues.apache.org/jira/browse/IGNITE-25369?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Konstantin Orlov updated IGNITE-25369:
--
Description: 
Apache Ignite is distributed system. It has an ability to have several copies 
of the data named replicas. Therefore, to execute a query, original plan is 
split on number of fragments, and every fragment is mapped on subset of nodes. 
It would be beneficial to provide an insight on which nodes will be used to 
execute which part of the query.

For this, let's introduce to command {{EXPLAIN MAPPING FOR }}. 
Below is suggested output of the command:
{code}
EXPLAIN MAPPING FOR SELECT 
U.UserName, P.ProductName, R.ReviewText, R.Rating
 FROM Users U, Reviews R, Products P
WHERE U.UserID = R.UserID
  AND R.ProductID = P.ProductID
  AND P.ProductName = 'Product_' || ?::varchar;

Fragment#0 root
  executionNodes: [ijot_n_3344]
  plan: 
Project
fields: [USERNAME, PRODUCTNAME, REVIEWTEXT, RATING]
exprs: [USERNAME, PRODUCTNAME, REVIEWTEXT, RATING]
est: (rows=1)
  HashJoin
  condition: =(USERID0, USERID)
  joinType: inner
  est: (rows=1)
HashJoin
condition: =(PRODUCTID, PRODUCTID0)
joinType: inner
est: (rows=1)
  Receiver
  rowType: RecordType(INTEGER PRODUCTID, INTEGER USERID, VARCHAR(65536) 
REVIEWTEXT, INTEGER RATING)
  exchangeId: 1
  sourceFragmentId: 1
  est: (rows=1)
  Receiver
  rowType: RecordType(INTEGER PRODUCTID, VARCHAR(100) PRODUCTNAME)
  exchangeId: 2
  sourceFragmentId: 2
  est: (rows=1)
Receiver
rowType: RecordType(INTEGER USERID, VARCHAR(100) USERNAME)
exchangeId: 3
sourceFragmentId: 3
est: (rows=1)

Fragment#1
  targetFragment: 0
  executionNodes: [ijot_n_3344, ijot_n_3345, ijot_n_3346]
  plan: 
Sender
exchangeId: 1
targetFragmentId: 0
distribution: single
est: (rows=5)
  TableScan
  table: PUBLIC.REVIEWS
  fields: [PRODUCTID, USERID, REVIEWTEXT, RATING]
  sourceId: 6
  est: (rows=5)

Fragment#2
  targetFragment: 0
  executionNodes: [ijot_n_3344, ijot_n_3345, ijot_n_3346]
  plan:
Sender
exchangeId: 2
targetFragmentId: 0
distribution: single
est: (rows=1665)
  TableScan
  table: PUBLIC.PRODUCTS
  filters: =(PRODUCTNAME, ||(_UTF-8'Product_', CAST(?0):VARCHAR CHARACTER 
SET "UTF-8"))
  fields: [PRODUCTID, PRODUCTNAME]
  sourceId: 5
  est: (rows=1665)

Fragment#3
  targetFragment: 0
  executionNodes: [ijot_n_3344, ijot_n_3345, ijot_n_3346]
  plan:
Sender
exchangeId: 3
targetFragmentId: 0
distribution: single
est: (rows=1)
  TableScan
  table: PUBLIC.USERS
  fields: [USERID, USERNAME]
  sourceId: 4
  est: (rows=1)

{code}

h3. Implementation Notes

As a first step, it worth to reuse 
{{org.apache.ignite.internal.sql.engine.exec.mapping.FragmentPrinter}} as is, 
and adjust output in follow up ticket (IGNITE-25413).

  was:
Apache Ignite is distributed system. It has an ability to have several copies 
of the data named replicas. Therefore, to execute a query, original plan is 
split on number of fragments, and every fragment is mapped on subset of nodes. 
It would be beneficial to provide an insight on which nodes will be used to 
execute which part of the query.

For this, let's introduce to command {{EXPLAIN MAPPING FOR }}. 
Below is suggested output of the command:
{code}
EXPLAIN MAPPING FOR SELECT 
U.UserName, P.ProductName, R.ReviewText, R.Rating
 FROM Users U, Reviews R, Products P
WHERE U.UserID = R.UserID
  AND R.ProductID = P.ProductID
  AND P.ProductName = 'Product_' || ?::varchar;

Fragment#0 root
  executionNodes: [ijot_n_3344]
  plan: 
Project
fields: [USERNAME, PRODUCTNAME, REVIEWTEXT, RATING]
exprs: [USERNAME, PRODUCTNAME, REVIEWTEXT, RATING]
est: (rows=1)
  HashJoin
  condition: =(USERID0, USERID)
  joinType: inner
  est: (rows=1)
HashJoin
condition: =(PRODUCTID, PRODUCTID0)
joinType: inner
est: (rows=1)
  Receiver
  rowType: RecordType(INTEGER PRODUCTID, INTEGER USERID, VARCHAR(65536) 
REVIEWTEXT, INTEGER RATING)
  exchangeId: 1
  sourceFragmentId: 1
  est: (rows=1)
  Receiver
  rowType: RecordType(INTEGER PRODUCTID, VARCHAR(100) PRODUCTNAME)
  exchangeId: 2
  sourceFragmentId: 2
  est: (rows=1)
Receiver
rowType: RecordType(INTEGER USERID, VARCHAR(100) USERNAME)
exchangeId: 3
sourceFragmentId: 3
est: (rows=1)

Fragment#1
  targetFragment: 0
  executionNodes: [ijot_n_3344, ijot_n_3345, ijot_n_3346]
  plan: 
Sender
exchangeId: 1
targetFragmentId: 0
distribution: single
est: (rows=5)
  TableScan
  table: PUBLIC.REVIEWS
  fields: [PRODUCTID, USERID, REVIEWTEXT, RATING]
  sourceId: 6
  est: (rows=500

[jira] [Updated] (IGNITE-25369) Sql. Introduce EXPLAIN MAPPING FOR command

2025-05-19 Thread Konstantin Orlov (Jira)


 [ 
https://issues.apache.org/jira/browse/IGNITE-25369?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Konstantin Orlov updated IGNITE-25369:
--
Description: 
Apache Ignite is distributed system. It has an ability to have several copies 
of the data named replicas. Therefore, to execute a query, original plan is 
split on number of fragments, and every fragment is mapped on subset of nodes. 
It would be beneficial to provide an insight on which nodes will be used to 
execute which part of the query.

For this, let's introduce to command {{EXPLAIN MAPPING FOR }}. 
Below is suggested output of the command:
{code}
EXPLAIN MAPPING FOR SELECT 
U.UserName, P.ProductName, R.ReviewText, R.Rating
 FROM Users U, Reviews R, Products P
WHERE U.UserID = R.UserID
  AND R.ProductID = P.ProductID
  AND P.ProductName = 'Product_' || ?::varchar;

Fragment#0 root
  executionNodes: [ijot_n_3344]
  plan: 
Project
fields: [USERNAME, PRODUCTNAME, REVIEWTEXT, RATING]
exprs: [USERNAME, PRODUCTNAME, REVIEWTEXT, RATING]
est: (rows=1)
  HashJoin
  condition: =(USERID0, USERID)
  joinType: inner
  est: (rows=1)
HashJoin
condition: =(PRODUCTID, PRODUCTID0)
joinType: inner
est: (rows=1)
  Receiver
  rowType: RecordType(INTEGER PRODUCTID, INTEGER USERID, VARCHAR(65536) 
REVIEWTEXT, INTEGER RATING)
  exchangeId: 1
  sourceFragmentId: 1
  est: (rows=1)
  Receiver
  rowType: RecordType(INTEGER PRODUCTID, VARCHAR(100) PRODUCTNAME)
  exchangeId: 2
  sourceFragmentId: 2
  est: (rows=1)
Receiver
rowType: RecordType(INTEGER USERID, VARCHAR(100) USERNAME)
exchangeId: 3
sourceFragmentId: 3
est: (rows=1)

Fragment#1
  targetFragment: 0
  executionNodes: [ijot_n_3344, ijot_n_3345, ijot_n_3346]
  plan: 
Sender
exchangeId: 1
targetFragmentId: 0
distribution: single
est: (rows=5)
  TableScan
  table: PUBLIC.REVIEWS
  fields: [PRODUCTID, USERID, REVIEWTEXT, RATING]
  sourceId: 6
  est: (rows=5)

Fragment#2
  targetFragment: 0
  executionNodes: [ijot_n_3344, ijot_n_3345, ijot_n_3346]
  plan:
Sender
exchangeId: 2
targetFragmentId: 0
distribution: single
est: (rows=1665)
  TableScan
  table: PUBLIC.PRODUCTS
  filters: =(PRODUCTNAME, ||(_UTF-8'Product_', CAST(?0):VARCHAR CHARACTER 
SET "UTF-8"))
  fields: [PRODUCTID, PRODUCTNAME]
  sourceId: 5
  est: (rows=1665)

Fragment#3
  targetFragment: 0
  executionNodes: [ijot_n_3344, ijot_n_3345, ijot_n_3346]
  plan:
Sender
exchangeId: 3
targetFragmentId: 0
distribution: single
est: (rows=1)
  TableScan
  table: PUBLIC.USERS
  fields: [USERID, USERNAME]
  sourceId: 4
  est: (rows=1)

{code}

h3. Implementation Notes

As a first step, it worth to reuse 
{{org.apache.ignite.internal.sql.engine.exec.mapping.FragmentPrinter}} as is, 
and adjust output in follow up ticket.

  was:
Apache Ignite is distributed system. It has an ability to have several copies 
of the data named replicas. Therefore, to execute a query, original plan is 
split on number of fragments, and every fragment is mapped on subset of nodes. 
It would be beneficial to provide an insight on which nodes will be used to 
execute which part of the query.

For this, let's introduce to command {{EXPLAIN MAPPING FOR }}. 
Below is suggested output of the command:
{code}
EXPLAIN MAPPING FOR SELECT 
U.UserName, P.ProductName, R.ReviewText, R.Rating
 FROM Users U, Reviews R, Products P
WHERE U.UserID = R.UserID
  AND R.ProductID = P.ProductID
  AND P.ProductName = 'Product_' || ?::varchar;

Fragment#0 root
  executionNodes: [ijot_n_3344]
  plan: 
Project
fields: [USERNAME, PRODUCTNAME, REVIEWTEXT, RATING]
exprs: [USERNAME, PRODUCTNAME, REVIEWTEXT, RATING]
est: (rows=1)
  HashJoin
  condition: =(USERID0, USERID)
  joinType: inner
  est: (rows=1)
HashJoin
condition: =(PRODUCTID, PRODUCTID0)
joinType: inner
est: (rows=1)
  Receiver
  rowType: RecordType(INTEGER PRODUCTID, INTEGER USERID, VARCHAR(65536) 
REVIEWTEXT, INTEGER RATING)
  exchangeId: 1
  sourceFragmentId: 1
  est: (rows=1)
  Receiver
  rowType: RecordType(INTEGER PRODUCTID, VARCHAR(100) PRODUCTNAME)
  exchangeId: 2
  sourceFragmentId: 2
  est: (rows=1)
Receiver
rowType: RecordType(INTEGER USERID, VARCHAR(100) USERNAME)
exchangeId: 3
sourceFragmentId: 3
est: (rows=1)

Fragment#1
  targetFragment: 0
  executionNodes: [ijot_n_3344, ijot_n_3345, ijot_n_3346]
  plan: 
Sender
exchangeId: 1
targetFragmentId: 0
distribution: single
est: (rows=5)
  TableScan
  table: PUBLIC.REVIEWS
  fields: [PRODUCTID, USERID, REVIEWTEXT, RATING]
  sourceId: 6
  est: (rows=5)

Fragment#2