Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add a second version implementation of get table schema and partition API. #41938

Merged

Conversation

plotor
Copy link
Contributor

@plotor plotor commented Feb 29, 2024

Why I'm doing:

You can learn about the background from PR #38466.

What I'm doing:

This is a relatively big feature, and we will split it into multiple PRs. Related PRs include:

This PR is one of them, which mainly add a second version implementation of get table schema and partition API. This version of the API is designed to be as neutral as possible, and not tied to specific scenarios. Howeaver, there are still some usage restrictions to note:

  1. Currently only supports OlapTable.
  2. This version of the API does not return all table schema and partition information. The current result response has satisfied the Bypass Write scenario. On the premise of ensuring compatibility, developers can gradually improve the interface according to their own business scenarios.

The API of Get Table Schema and Partition are defined as follows:

Get Table Schema API Definition

  • Path: /api/v2/catalogs/{catalog}/databases/{db}/tables/{table}/schema
  • Method: GET
  • Parameter:
Name Type Required Default Desc
catalog string no default_catalog Path Parameter, Represents the data catalog name
db string yes Path Parameter, Represents the database name
table string yes Path Parameter, Represents the table name
  • Response:

Response Example:

{
  "code": "0",
  "message": "OK",
  "result": {
    "id": 10200,
    "name": "tb_table_schema_test",
    "tableType": "OLAP",
    "keysType": "DUP_KEYS",
    "comment": "c_tb_table_schema_test",
    "createTime": 1709197545,
    "columns": [
      {
        "name": "c1",
        "primitiveType": "DOUBLE",
        "primitiveTypeSize": 8,
        "columnSize": 15,
        "precision": 0,
        "scale": 0,
        "isKey": true,
        "isAllowNull": false,
        "isAutoIncrement": false,
        "defaultValueType": "NULL",
        "comment": "cc1",
        "uniqueId": 1
      },
      {
        "name": "c2",
        "primitiveType": "DECIMAL64",
        "primitiveTypeSize": 8,
        "columnSize": 18,
        "precision": 18,
        "scale": 6,
        "aggregationType": "SUM",
        "isKey": false,
        "isAllowNull": true,
        "isAutoIncrement": false,
        "defaultValueType": "CONST",
        "defaultValue": "0",
        "comment": "cc2",
        "uniqueId": 2
      }
    ],
    "indexMetas": [
      {
        "indexId": 10200,
        "keysType": "DUP_KEYS",
        "columns": [
          {
            "name": "c1",
            "primitiveType": "DOUBLE",
            "primitiveTypeSize": 8,
            "columnSize": 15,
            "precision": 0,
            "scale": 0,
            "isKey": true,
            "isAllowNull": false,
            "isAutoIncrement": false,
            "defaultValueType": "NULL",
            "comment": "cc1",
            "uniqueId": 1
          }
        ]
      }
    ],
    "partitionInfo": {
      "type": "RANGE",
      "partitionColumns": [
        {
          "name": "c1",
          "primitiveType": "DOUBLE",
          "primitiveTypeSize": 8,
          "columnSize": 15,
          "precision": 0,
          "scale": 0,
          "isKey": true,
          "isAllowNull": false,
          "isAutoIncrement": false,
          "defaultValueType": "NULL",
          "comment": "cc1",
          "uniqueId": 1
        }
      ]
    },
    "defaultDistributionInfo": {
      "type": "HASH",
      "bucketNum": 8,
      "distributionColumns": [
        {
          "name": "c1",
          "primitiveType": "DOUBLE",
          "primitiveTypeSize": 8,
          "columnSize": 15,
          "precision": 0,
          "scale": 0,
          "isKey": true,
          "isAllowNull": false,
          "isAutoIncrement": false,
          "defaultValueType": "NULL",
          "comment": "cc1",
          "uniqueId": 1
        }
      ]
    },
    "colocateGroup": "cg1",
    "indexes": [
      {
        "indexId": 10200,
        "indexName": "idx1",
        "indexType": "BITMAP",
        "columns": [
          "c1"
        ],
        "comment": "c_idx1",
        "properties": {}
      },
      {
        "indexId": 10201,
        "indexName": "idx2",
        "indexType": "NGRAMBF",
        "columns": [
          "c2"
        ],
        "comment": "c_idx2",
        "properties": {}
      }
    ],
    "baseIndexId": 10200,
    "maxIndexId": 75735,
    "maxColUniqueId": 65535,
    "properties": {
      "replication_num": "3",
      "colocate_with": "cg1"
    }
  }
}

Get Table Partition API Definition

  • Path: /api/v2/catalogs/{catalog}/databases/{db}/tables/{table}/partition
  • Method: GET
  • Parameter:
Name Type Required Default Desc
catalog string no default_catalog Path Parameter, Represents the data catalog name
db string yes Path Parameter, Represents the database name
table string yes Path Parameter, Represents the table name
temporary boolean no false Query Parameter, if set to true, If set to true, it means get temporary partition info
  • Response:

The response template is as follows:

{
  "code": "0",
  "message": "OK",
  "result": {
    "pageNum": 1,
    "pageSize": 7,
    "pages": 1,
    "total": 7,
    "items": []
  }
}

Parameter description:

  • pageNum: the page number in request.
  • pageSize: the page size in request.
  • pages: total page size.
  • total: total item size.
  • items: data items.

Response Example:

{
  "code": "0",
  "message": "OK",
  "result": {
    "pageNum": 1,
    "pageSize": 3,
    "pages": 3,
    "total": 7,
    "items": [
      {
        "id": 11204,
        "name": "testPartition_3",
        "bucketNum": 8,
        "distributionType": "HASH",
        "visibleVersion": 12,
        "visibleVersionTime": 1711351506629,
        "nextVersion": 13,
        "isMinPartition": false,
        "isMaxPartition": false,
        "startKeys": [
          30.0
        ],
        "endKeys": [
          40.0
        ],
        "tablets": [
          {
            "id": 400,
            "backendIds": [
              1000,
              1001,
              1002
            ]
          }
        ]
      },
      {
        "id": 11205,
        "name": "testPartition_4",
        "bucketNum": 8,
        "distributionType": "HASH",
        "visibleVersion": 12,
        "visibleVersionTime": 1711351506629,
        "nextVersion": 13,
        "isMinPartition": false,
        "isMaxPartition": false,
        "startKeys": [
          40.0
        ],
        "endKeys": [
          50.0
        ],
        "tablets": [
          {
            "id": 400,
            "backendIds": [
              1000,
              1001,
              1002
            ]
          }
        ]
      },
      {
        "id": 11206,
        "name": "testPartition_5",
        "bucketNum": 8,
        "distributionType": "HASH",
        "visibleVersion": 12,
        "visibleVersionTime": 1711351506629,
        "nextVersion": 13,
        "isMinPartition": false,
        "isMaxPartition": false,
        "startKeys": [
          50.0
        ],
        "endKeys": [
          60.0
        ],
        "tablets": [
          {
            "id": 400,
            "backendIds": [
              1000,
              1001,
              1002
            ]
          }
        ]
      }
    ]
  }
}

Fixes #issue

What type of PR is this:

  • BugFix
  • Feature
  • Enhancement
  • Refactor
  • UT
  • Doc
  • Tool

Does this PR entail a change in behavior?

  • Yes, this PR will result in a change in behavior.
  • No, this PR will not result in a change in behavior.

If yes, please specify the type of change:

  • Interface/UI changes: syntax, type conversion, expression evaluation, display information
  • Parameter changes: default values, similar parameters but with different default values
  • Policy changes: use new policy to replace old one, functionality automatically enabled
  • Feature removed
  • Miscellaneous: upgrade & downgrade compatibility, etc.

Checklist:

  • I have added test cases for my bug fix or my new feature
  • This pr needs user documentation (for new or modified features or behaviors)
    • I have added documentation for my new feature or new function
  • This is a backport pr

Bugfix cherry-pick branch check:

  • I have checked the version labels which the pr will be auto-backported to the target branch
    • 3.2
    • 3.1
    • 3.0
    • 2.5

@plotor plotor requested a review from a team as a code owner February 29, 2024 09:54
@mergify mergify bot assigned plotor Feb 29, 2024
satanson
satanson previously approved these changes Mar 5, 2024
@plotor plotor force-pushed the feature-table-schema-api-v2-zhenchao-20240227 branch from 5fcb372 to 204eea9 Compare March 20, 2024 07:43
@plotor plotor force-pushed the feature-table-schema-api-v2-zhenchao-20240227 branch 4 times, most recently from 3ecf130 to cccd226 Compare March 25, 2024 07:06
@plotor plotor requested review from a team as code owners March 25, 2024 07:06
@plotor plotor force-pushed the feature-table-schema-api-v2-zhenchao-20240227 branch from cccd226 to e91bd5b Compare March 25, 2024 07:21
@plotor plotor changed the title [Feature] Add a second version implementation of get table schema API. [Feature] Add a second version implementation of get table schema and partition API. Mar 25, 2024
kevincai
kevincai previously approved these changes Mar 28, 2024
@@ -197,4 +219,42 @@ public boolean redirectToLeader(BaseRequest request, BaseResponse response) thro
new TNetworkAddress(leaderIpAndPort.first, leaderIpAndPort.second));
return true;
}

protected static String getParameter(BaseRequest request, String paramName) {
Copy link
Contributor

Choose a reason for hiding this comment

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

while these getParameters are good help functions, thinking about a few improvements,

  • getParameter() return null if the paremter doesn't exist, it is up to the caller to determine what to do.
  • getParameterRequired() throws BAD_REQUEST http exception if the parameter is not there.
  • getParameterOrDefault() returns default value if the parameter is not there.
  • generic programming, getParameter for int/boolean/string/double/...,
    org.apache.hadoop.conf.Configuration might be a good reference for these interfaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kevincai Good suggestions.

@plotor plotor force-pushed the feature-table-schema-api-v2-zhenchao-20240227 branch from e91bd5b to 26e5330 Compare March 28, 2024 07:22
@wanpengfei-git wanpengfei-git requested a review from a team March 28, 2024 07:22
gengjun-git
gengjun-git previously approved these changes Mar 28, 2024
kevincai
kevincai previously approved these changes Mar 28, 2024
satanson
satanson previously approved these changes Mar 28, 2024
@nshangyiming nshangyiming self-assigned this Mar 28, 2024
.orElse(DEFAULT_INTERNAL_CATALOG_NAME).equalsIgnoreCase(catalogName)) {
throw new StarRocksHttpException(
HttpResponseStatus.NOT_FOUND,
String.format("Database[%s] does not exist in catalog %s", dbName, catalogName)
Copy link
Contributor

Choose a reason for hiding this comment

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

Will this message be shown to users?
If yes, put it into ErrorCode.java

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, and I found that I can reuse some existing ErrorCode.

if (null == table) {
throw new StarRocksHttpException(
HttpResponseStatus.NOT_FOUND,
String.format("Table[%s.%s] does not exist in catalog %s", dbName, tableName, catalogName)
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above.


OlapTable olapTable = getOlapTable(catalogName, dbName, tableName);
Collection<Partition> partitions =
temporary ? olapTable.getTempPartitions() : olapTable.getPartitions();
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to lock the table to get a partition snapshot?
Or will the olapTable be modified when geting partitions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, It is a problem, and i encapsulated the processing logic of OlapTable into the db read lock.

Comment on lines 74 to 88
Collection<Partition> partitions =
temporary ? olapTable.getTempPartitions() : olapTable.getPartitions();
if (CollectionUtils.isNotEmpty(partitions)) {
int pages = partitions.size() / pageSize;
pagedResult.setPages(partitions.size() % pageSize == 0 ? pages : (pages + 1));
pagedResult.setTotal(partitions.size());
pagedResult.setItems(partitions.stream()
.sorted(Comparator.comparingLong(Partition::getId))
.skip((long) pageNum * pageSize)
.limit(pageSize)
.map(partition ->
TablePartitionView.createFrom(olapTable.getPartitionInfo(), partition))
.collect(Collectors.toList())
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

need read lock

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, It is a problem, and i encapsulated the processing logic of OlapTable into the db read lock.

String tableName = getSingleParameterRequired(request, TABLE_KEY, Function.identity());

OlapTable olapTable = getOlapTable(catalogName, dbName, tableName);
sendResult(request, response, new RestBaseResultV2<>(TableSchemaView.createFrom(olapTable)));
Copy link
Contributor

Choose a reason for hiding this comment

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

need read lock

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, It is a problem, and i encapsulated the processing logic of OlapTable into the db read lock.

@plotor plotor dismissed stale reviews from satanson, kevincai, and gengjun-git via f5acdcd March 28, 2024 13:31
@plotor plotor force-pushed the feature-table-schema-api-v2-zhenchao-20240227 branch 2 times, most recently from f5acdcd to 6271a96 Compare March 28, 2024 14:23
wyb
wyb previously approved these changes Mar 29, 2024
@@ -110,7 +122,7 @@ public String getErrorRespWhenUnauthorized(AccessDeniedException accessDeniedExc
List<String> activatedRoles = authorizationMgr.getRoleNamesByRoleIds(context.getCurrentRoleIds());
List<String> inactivatedRoles =
authorizationMgr.getInactivatedRoleNamesByUser(userIdentity, activatedRoles);
return "Access denied for user " + userIdentity + ". " +
return "Access denied for user " + userIdentity + ". " +
Copy link
Contributor

Choose a reason for hiding this comment

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

You can use ErrorCode.ERR_AUTHENTICATION_FAIL

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change is caused by code formatting, and have nothing to do with the business logic of this PR. I have rolled it back to make this PR more focused.

@@ -110,7 +122,7 @@ public String getErrorRespWhenUnauthorized(AccessDeniedException accessDeniedExc
List<String> activatedRoles = authorizationMgr.getRoleNamesByRoleIds(context.getCurrentRoleIds());
List<String> inactivatedRoles =
authorizationMgr.getInactivatedRoleNamesByUser(userIdentity, activatedRoles);
return "Access denied for user " + userIdentity + ". " +
return "Access denied for user " + userIdentity + ". " +
String.format(ErrorCode.ERR_ACCESS_DENIED_HINT_MSG_FORMAT, activatedRoles, inactivatedRoles);
}
return "Access denied.";
Copy link
Contributor

Choose a reason for hiding this comment

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

Will it be too simple to let user know the error reason?

Copy link
Contributor

Choose a reason for hiding this comment

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

this is intended to do so, because we cannot get any more specific info.

} else if (dateLiteral.getType().isDatetime()) {
return dateLiteral.getLongValue();
} else {
throw new StarRocksPlannerException("Invalid date type: " + dateLiteral.getType(), ErrorType.INTERNAL_ERROR);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can be put into ErrorCode?

import java.util.Optional;
import java.util.stream.Collectors;

public class TablePartitionView {
Copy link
Contributor

Choose a reason for hiding this comment

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

can this class be merged with PartitionInfoView?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nshangyiming
nshangyiming previously approved these changes Mar 29, 2024
Copy link
Contributor

@nshangyiming nshangyiming left a comment

Choose a reason for hiding this comment

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

LGTM

@plotor plotor dismissed stale reviews from nshangyiming and wyb via 9085e31 March 29, 2024 09:43
@plotor plotor force-pushed the feature-table-schema-api-v2-zhenchao-20240227 branch from 6271a96 to 9085e31 Compare March 29, 2024 09:43
Copy link
Contributor

@jaogoy jaogoy left a comment

Choose a reason for hiding this comment

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

The error msgs LGTM

@nshangyiming
Copy link
Contributor

@mergify rebase

Copy link
Contributor

mergify bot commented Apr 1, 2024

rebase

✅ Branch has been successfully rebased

@nshangyiming nshangyiming force-pushed the feature-table-schema-api-v2-zhenchao-20240227 branch from 9085e31 to 58f48d0 Compare April 1, 2024 03:04
Copy link

sonarqubecloud bot commented Apr 1, 2024

Copy link

github-actions bot commented Apr 1, 2024

[FE Incremental Coverage Report]

pass : 526 / 559 (94.10%)

file detail

path covered_line new_line coverage not_covered_line_detail
🔵 com/starrocks/http/rest/v2/TableBaseAction.java 24 35 68.57% [58, 59, 60, 61, 62, 64, 65, 94, 95, 104, 105]
🔵 com/starrocks/http/rest/RestBaseAction.java 20 24 83.33% [191, 235, 252, 254]
🔵 com/starrocks/load/loadv2/SparkLoadPendingTask.java 6 7 85.71% [420]
🔵 com/starrocks/http/rest/v2/vo/PartitionInfoView.java 94 104 90.38% [56, 149, 150, 151, 152, 153, 183, 184, 251, 259]
🔵 com/starrocks/load/PartitionUtils.java 35 38 92.11% [177, 194, 217]
🔵 com/starrocks/http/rest/v2/vo/DistributionInfoView.java 25 27 92.59% [59, 60]
🔵 com/starrocks/http/rest/v2/vo/ColumnView.java 70 72 97.22% [212, 213]
🔵 com/starrocks/http/rest/v2/vo/IndexView.java 30 30 100.00% []
🔵 com/starrocks/http/rest/v2/RestBaseResultV2.java 40 40 100.00% []
🔵 com/starrocks/http/rest/v2/TablePartitionAction.java 34 34 100.00% []
🔵 com/starrocks/http/rest/v2/vo/TabletView.java 20 20 100.00% []
🔵 com/starrocks/http/rest/RestBaseResult.java 2 2 100.00% []
🔵 com/starrocks/http/rest/v2/TableSchemaAction.java 12 12 100.00% []
🔵 com/starrocks/http/rest/v2/vo/TableSchemaView.java 89 89 100.00% []
🔵 com/starrocks/catalog/DistributionInfo.java 1 1 100.00% []
🔵 com/starrocks/http/rest/v2/vo/MaterializedIndexMetaView.java 22 22 100.00% []
🔵 com/starrocks/http/HttpServer.java 2 2 100.00% []

Copy link

github-actions bot commented Apr 1, 2024

[BE Incremental Coverage Report]

pass : 0 / 0 (0%)

@meegoo meegoo enabled auto-merge (squash) April 1, 2024 06:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants