frontend/instance/
copy_in.rs1use api::v1::RowInsertRequests;
16use async_trait::async_trait;
17use auth::{PermissionChecker, PermissionCheckerRef, PermissionReq};
18use common_error::ext::BoxedError;
19use common_query::Output;
20use query::query_engine::options::{QueryOptions, validate_catalog_and_schema};
21use servers::error::{AuthSnafu, ExecuteGrpcRequestSnafu, ExecuteQuerySnafu, Result};
22use servers::query_handler::CopyInHandler;
23use session::context::QueryContextRef;
24use snafu::ResultExt;
25use table::metadata::TableInfoRef;
26
27use crate::instance::Instance;
28
29#[async_trait]
30impl CopyInHandler for Instance {
31 async fn copy_in_table(
32 &self,
33 catalog: &str,
34 schema: &str,
35 table: &str,
36 query_ctx: QueryContextRef,
37 ) -> Result<Option<TableInfoRef>> {
38 let disallow_cross_catalog_query = self
45 .plugins
46 .get::<QueryOptions>()
47 .map(|opts| opts.disallow_cross_catalog_query)
48 .unwrap_or_default();
49 if disallow_cross_catalog_query {
50 validate_catalog_and_schema(catalog, schema, &query_ctx)
51 .map_err(BoxedError::new)
52 .context(ExecuteQuerySnafu)?;
53 }
54
55 self.plugins
58 .get::<PermissionCheckerRef>()
59 .as_ref()
60 .check_permission(
61 query_ctx.current_user(),
62 PermissionReq::BulkInsert {
63 catalog,
64 schema,
65 table,
66 },
67 )
68 .context(AuthSnafu)?;
69
70 self.catalog_manager()
71 .table(catalog, schema, table, None)
72 .await
73 .map(|table| table.map(|table| table.table_info()))
74 .map_err(servers::error::Error::from)
75 }
76
77 async fn copy_in_insert(
78 &self,
79 requests: RowInsertRequests,
80 query_ctx: QueryContextRef,
81 ) -> Result<Output> {
82 self.handle_row_inserts(requests, query_ctx, false, false)
83 .await
84 .map_err(BoxedError::new)
85 .context(ExecuteGrpcRequestSnafu)
86 }
87}