mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-10-29 07:06:20 +00:00
fix: security fix, sqlx, hashbrown, idna and CI updates (#5330)
* fix: security fix, sqlx, hashbrown, idna * ci: optimize ci cache generation * feat: update pprof
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 15 * * 1-5"
|
||||
merge_group:
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened, ready_for_review ]
|
||||
@@ -51,12 +53,6 @@ jobs:
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
# - name: Rust Cache
|
||||
# uses: Swatinem/rust-cache@v2
|
||||
# with:
|
||||
# # Shares across multiple jobs
|
||||
# # Shares with `Clippy` job
|
||||
# shared-key: "check-lint"
|
||||
- name: Run cargo check
|
||||
run: cargo check --locked --workspace --all-targets
|
||||
|
||||
@@ -67,11 +63,6 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
# - name: Rust Cache
|
||||
# uses: Swatinem/rust-cache@v2
|
||||
# with:
|
||||
# # Shares across multiple jobs
|
||||
# shared-key: "check-toml"
|
||||
- name: Install taplo
|
||||
run: cargo +stable install taplo-cli --version ^0.9 --locked --force
|
||||
- name: Run taplo
|
||||
@@ -94,6 +85,8 @@ jobs:
|
||||
with:
|
||||
# Shares across multiple jobs
|
||||
shared-key: "build-binaries"
|
||||
cache-all-crates: "true"
|
||||
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||
- name: Install cargo-gc-bin
|
||||
shell: bash
|
||||
run: cargo install cargo-gc-bin --force
|
||||
@@ -142,11 +135,6 @@ jobs:
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
# - name: Rust Cache
|
||||
# uses: Swatinem/rust-cache@v2
|
||||
# with:
|
||||
# # Shares across multiple jobs
|
||||
# shared-key: "fuzz-test-targets"
|
||||
- name: Set Rust Fuzz
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -200,11 +188,6 @@ jobs:
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
# - name: Rust Cache
|
||||
# uses: Swatinem/rust-cache@v2
|
||||
# with:
|
||||
# # Shares across multiple jobs
|
||||
# shared-key: "fuzz-test-targets"
|
||||
- name: Set Rust Fuzz
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -255,6 +238,8 @@ jobs:
|
||||
with:
|
||||
# Shares across multiple jobs
|
||||
shared-key: "build-greptime-ci"
|
||||
cache-all-crates: "true"
|
||||
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||
- name: Install cargo-gc-bin
|
||||
shell: bash
|
||||
run: cargo install cargo-gc-bin --force
|
||||
@@ -317,11 +302,6 @@ jobs:
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
# - name: Rust Cache
|
||||
# uses: Swatinem/rust-cache@v2
|
||||
# with:
|
||||
# # Shares across multiple jobs
|
||||
# shared-key: "fuzz-test-targets"
|
||||
- name: Set Rust Fuzz
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -466,11 +446,6 @@ jobs:
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
# - name: Rust Cache
|
||||
# uses: Swatinem/rust-cache@v2
|
||||
# with:
|
||||
# # Shares across multiple jobs
|
||||
# shared-key: "fuzz-test-targets"
|
||||
- name: Set Rust Fuzz
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -612,11 +587,6 @@ jobs:
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
components: rustfmt
|
||||
# - name: Rust Cache
|
||||
# uses: Swatinem/rust-cache@v2
|
||||
# with:
|
||||
# # Shares across multiple jobs
|
||||
# shared-key: "check-rust-fmt"
|
||||
- name: Check format
|
||||
run: make fmt-check
|
||||
|
||||
@@ -638,6 +608,8 @@ jobs:
|
||||
# Shares across multiple jobs
|
||||
# Shares with `Check` job
|
||||
shared-key: "check-lint"
|
||||
cache-all-crates: "true"
|
||||
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||
- name: Run cargo clippy
|
||||
run: make clippy
|
||||
|
||||
@@ -670,6 +642,7 @@ jobs:
|
||||
with:
|
||||
# Shares cross multiple jobs
|
||||
shared-key: "coverage-test"
|
||||
cache-all-crates: "true"
|
||||
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||
# Disabled temporarily to see performance
|
||||
# - name: Docker Cache
|
||||
|
||||
@@ -108,51 +108,6 @@ jobs:
|
||||
GT_S3_REGION: ${{ vars.AWS_CI_TEST_BUCKET_REGION }}
|
||||
UNITTEST_LOG_DIR: "__unittest_logs"
|
||||
|
||||
## this is designed for generating cache that usable for pull requests
|
||||
test-on-linux:
|
||||
name: Run tests on Linux
|
||||
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||
runs-on: ubuntu-20.04-8-cores
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: arduino/setup-protoc@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: rui314/setup-mold@v1
|
||||
- name: Install Rust toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
# Shares cross multiple jobs
|
||||
shared-key: "coverage-test"
|
||||
- name: Install Cargo Nextest
|
||||
uses: taiki-e/install-action@nextest
|
||||
- name: Setup external services
|
||||
working-directory: tests-integration/fixtures
|
||||
run: docker compose up -d --wait
|
||||
- name: Running tests
|
||||
run: cargo nextest run -F dashboard -F pg_kvbackend
|
||||
env:
|
||||
CARGO_BUILD_RUSTFLAGS: "-C link-arg=-fuse-ld=mold"
|
||||
RUST_BACKTRACE: 1
|
||||
CARGO_INCREMENTAL: 0
|
||||
GT_S3_BUCKET: ${{ vars.AWS_CI_TEST_BUCKET }}
|
||||
GT_S3_ACCESS_KEY_ID: ${{ secrets.AWS_CI_TEST_ACCESS_KEY_ID }}
|
||||
GT_S3_ACCESS_KEY: ${{ secrets.AWS_CI_TEST_SECRET_ACCESS_KEY }}
|
||||
GT_S3_REGION: ${{ vars.AWS_CI_TEST_BUCKET_REGION }}
|
||||
GT_MINIO_BUCKET: greptime
|
||||
GT_MINIO_ACCESS_KEY_ID: superpower_ci_user
|
||||
GT_MINIO_ACCESS_KEY: superpower_password
|
||||
GT_MINIO_REGION: us-west-2
|
||||
GT_MINIO_ENDPOINT_URL: http://127.0.0.1:9000
|
||||
GT_ETCD_ENDPOINTS: http://127.0.0.1:2379
|
||||
GT_POSTGRES_ENDPOINTS: postgres://greptimedb:admin@127.0.0.1:5432/postgres
|
||||
GT_KAFKA_ENDPOINTS: 127.0.0.1:9092
|
||||
GT_KAFKA_SASL_ENDPOINTS: 127.0.0.1:9093
|
||||
UNITTEST_LOG_DIR: "__unittest_logs"
|
||||
|
||||
cleanbuild-linux-nix:
|
||||
name: Run clean build on Linux
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
|
||||
Generated
+549
-287
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@ snafu.workspace = true
|
||||
tokio.workspace = true
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
pprof = { version = "0.13", features = [
|
||||
pprof = { version = "0.14", features = [
|
||||
"flamegraph",
|
||||
"prost-codec",
|
||||
"protobuf",
|
||||
|
||||
@@ -53,7 +53,7 @@ serde_yaml = "0.9"
|
||||
snafu = { workspace = true }
|
||||
sql = { workspace = true }
|
||||
sqlparser.workspace = true
|
||||
sqlx = { version = "0.6", features = [
|
||||
sqlx = { version = "0.8", features = [
|
||||
"runtime-tokio-rustls",
|
||||
"mysql",
|
||||
"postgres",
|
||||
|
||||
@@ -59,8 +59,11 @@ pub async fn init_greptime_connections_via_env() -> Connections {
|
||||
/// Connects to GreptimeDB.
|
||||
pub async fn init_greptime_connections(mysql: Option<String>) -> Connections {
|
||||
let mysql = if let Some(addr) = mysql {
|
||||
let mut opts: MySqlConnectOptions = format!("mysql://{addr}/public").parse().unwrap();
|
||||
opts.log_statements(LevelFilter::Off);
|
||||
let opts = format!("mysql://{addr}/public")
|
||||
.parse::<MySqlConnectOptions>()
|
||||
.unwrap()
|
||||
.log_statements(LevelFilter::Off);
|
||||
|
||||
Some(MySqlPoolOptions::new().connect_with(opts).await.unwrap())
|
||||
} else {
|
||||
None
|
||||
|
||||
@@ -17,8 +17,7 @@ use std::time::Duration;
|
||||
use common_telemetry::info;
|
||||
use humantime::parse_duration;
|
||||
use snafu::ResultExt;
|
||||
use sqlx::database::HasArguments;
|
||||
use sqlx::{ColumnIndex, Database, Decode, Encode, Executor, IntoArguments, MySql, Pool, Type};
|
||||
use sqlx::MySqlPool;
|
||||
|
||||
use super::wait::wait_condition_fn;
|
||||
use crate::error::{self, Result};
|
||||
@@ -34,19 +33,10 @@ pub struct NodeInfo {
|
||||
}
|
||||
|
||||
/// Returns all [NodeInfo] in the cluster.
|
||||
pub async fn fetch_nodes<'a, DB, E>(e: E) -> Result<Vec<NodeInfo>>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as HasArguments<'a>>::Arguments: IntoArguments<'a, DB>,
|
||||
for<'c> E: 'a + Executor<'c, Database = DB>,
|
||||
for<'c> i64: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> String: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> String: Encode<'c, DB> + Type<DB>,
|
||||
for<'c> &'c str: ColumnIndex<<DB as Database>::Row>,
|
||||
{
|
||||
let sql = "select * from information_schema.cluster_info;";
|
||||
pub async fn fetch_nodes(db: &MySqlPool) -> Result<Vec<NodeInfo>> {
|
||||
let sql = "select * from information_schema.cluster_info";
|
||||
sqlx::query_as::<_, NodeInfo>(sql)
|
||||
.fetch_all(e)
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.context(error::ExecuteQuerySnafu { sql })
|
||||
}
|
||||
@@ -55,7 +45,7 @@ where
|
||||
///
|
||||
/// This function repeatedly checks the status of all datanodes and waits until all of them are online
|
||||
/// or the timeout period elapses. A datanode is considered online if its `active_time` is less than 3 seconds.
|
||||
pub async fn wait_for_all_datanode_online(greptime: Pool<MySql>, timeout: Duration) {
|
||||
pub async fn wait_for_all_datanode_online(greptime: MySqlPool, timeout: Duration) {
|
||||
wait_condition_fn(
|
||||
timeout,
|
||||
|| {
|
||||
|
||||
@@ -17,8 +17,7 @@ use std::time::Duration;
|
||||
|
||||
use common_telemetry::info;
|
||||
use snafu::ResultExt;
|
||||
use sqlx::database::HasArguments;
|
||||
use sqlx::{ColumnIndex, Database, Decode, Encode, Executor, IntoArguments, MySql, Pool, Type};
|
||||
use sqlx::MySqlPool;
|
||||
use store_api::storage::RegionId;
|
||||
|
||||
use super::wait::wait_condition_fn;
|
||||
@@ -36,61 +35,33 @@ pub struct PartitionCount {
|
||||
pub count: i64,
|
||||
}
|
||||
|
||||
pub async fn count_partitions<'a, DB, E>(e: E, datanode_id: u64) -> Result<PartitionCount>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as HasArguments<'a>>::Arguments: IntoArguments<'a, DB>,
|
||||
for<'c> E: 'a + Executor<'c, Database = DB>,
|
||||
for<'c> i64: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> String: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> u64: Encode<'c, DB> + Type<DB>,
|
||||
for<'c> &'c str: ColumnIndex<<DB as Database>::Row>,
|
||||
{
|
||||
pub async fn count_partitions(db: &MySqlPool, datanode_id: u64) -> Result<PartitionCount> {
|
||||
let sql = "select count(1) as count from information_schema.region_peers where peer_id == ?";
|
||||
Ok(sqlx::query_as::<_, PartitionCount>(sql)
|
||||
sqlx::query_as::<_, PartitionCount>(sql)
|
||||
.bind(datanode_id)
|
||||
.fetch_all(e)
|
||||
.fetch_one(db)
|
||||
.await
|
||||
.context(error::ExecuteQuerySnafu { sql })?
|
||||
.remove(0))
|
||||
.context(error::ExecuteQuerySnafu { sql })
|
||||
}
|
||||
|
||||
/// Returns the [Partition] of the specific `region_id`
|
||||
pub async fn fetch_partition<'a, DB, E>(e: E, region_id: u64) -> Result<Partition>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as HasArguments<'a>>::Arguments: IntoArguments<'a, DB>,
|
||||
for<'c> E: 'a + Executor<'c, Database = DB>,
|
||||
for<'c> u64: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> String: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> u64: Encode<'c, DB> + Type<DB>,
|
||||
for<'c> &'c str: ColumnIndex<<DB as Database>::Row>,
|
||||
{
|
||||
pub async fn fetch_partition(db: &MySqlPool, region_id: u64) -> Result<Partition> {
|
||||
let sql = "select region_id, peer_id as datanode_id from information_schema.region_peers where region_id = ?;";
|
||||
sqlx::query_as::<_, Partition>(sql)
|
||||
.bind(region_id)
|
||||
.fetch_one(e)
|
||||
.fetch_one(db)
|
||||
.await
|
||||
.context(error::ExecuteQuerySnafu { sql })
|
||||
}
|
||||
|
||||
/// Returns all [Partition] of the specific `table`
|
||||
pub async fn fetch_partitions<'a, DB, E>(e: E, table_name: Ident) -> Result<Vec<Partition>>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as HasArguments<'a>>::Arguments: IntoArguments<'a, DB>,
|
||||
for<'c> E: 'a + Executor<'c, Database = DB>,
|
||||
for<'c> u64: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> String: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> String: Encode<'c, DB> + Type<DB>,
|
||||
for<'c> &'c str: ColumnIndex<<DB as Database>::Row>,
|
||||
{
|
||||
pub async fn fetch_partitions(db: &MySqlPool, table_name: Ident) -> Result<Vec<Partition>> {
|
||||
let sql = "select b.peer_id as datanode_id, a.greptime_partition_id as region_id
|
||||
from information_schema.partitions a left join information_schema.region_peers b
|
||||
on a.greptime_partition_id = b.region_id where a.table_name= ? order by datanode_id asc;";
|
||||
sqlx::query_as::<_, Partition>(sql)
|
||||
.bind(table_name.value.to_string())
|
||||
.fetch_all(e)
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.context(error::ExecuteQuerySnafu { sql })
|
||||
}
|
||||
@@ -124,7 +95,7 @@ pub fn pretty_print_region_distribution(distribution: &BTreeMap<u64, Vec<RegionI
|
||||
/// This function repeatedly checks the number of partitions on the specified datanode and waits until
|
||||
/// the count reaches zero or the timeout period elapses. It logs the number of partitions on each check.
|
||||
pub async fn wait_for_all_regions_evicted(
|
||||
greptime: Pool<MySql>,
|
||||
greptime: MySqlPool,
|
||||
selected_datanode: u64,
|
||||
timeout: Duration,
|
||||
) {
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
use common_telemetry::debug;
|
||||
use datatypes::data_type::DataType;
|
||||
use snafu::{ensure, ResultExt};
|
||||
use sqlx::database::HasArguments;
|
||||
use sqlx::{ColumnIndex, Database, Decode, Encode, Executor, IntoArguments, Type};
|
||||
use sqlx::MySqlPool;
|
||||
|
||||
use crate::error::{self, Result};
|
||||
use crate::ir::create_expr::ColumnOption;
|
||||
@@ -198,24 +197,16 @@ pub fn assert_eq(fetched_columns: &[ColumnEntry], columns: &[Column]) -> Result<
|
||||
}
|
||||
|
||||
/// Returns all [ColumnEntry] of the `table_name` from `information_schema`.
|
||||
pub async fn fetch_columns<'a, DB, E>(
|
||||
e: E,
|
||||
pub async fn fetch_columns(
|
||||
db: &MySqlPool,
|
||||
schema_name: Ident,
|
||||
table_name: Ident,
|
||||
) -> Result<Vec<ColumnEntry>>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as HasArguments<'a>>::Arguments: IntoArguments<'a, DB>,
|
||||
for<'c> E: 'a + Executor<'c, Database = DB>,
|
||||
for<'c> String: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> String: Encode<'c, DB> + Type<DB>,
|
||||
for<'c> &'c str: ColumnIndex<<DB as Database>::Row>,
|
||||
{
|
||||
) -> Result<Vec<ColumnEntry>> {
|
||||
let sql = "SELECT table_schema, table_name, column_name, greptime_data_type as data_type, semantic_type, column_default, is_nullable FROM information_schema.columns WHERE table_schema = ? AND table_name = ?";
|
||||
sqlx::query_as::<_, ColumnEntry>(sql)
|
||||
.bind(schema_name.value.to_string())
|
||||
.bind(table_name.value.to_string())
|
||||
.fetch_all(e)
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.context(error::ExecuteQuerySnafu { sql })
|
||||
}
|
||||
|
||||
@@ -17,11 +17,8 @@ use common_time::date::Date;
|
||||
use common_time::{DateTime, Timestamp};
|
||||
use datatypes::value::Value;
|
||||
use snafu::{ensure, ResultExt};
|
||||
use sqlx::database::HasArguments;
|
||||
use sqlx::{
|
||||
Column, ColumnIndex, Database, Decode, Encode, Executor, IntoArguments, Row, Type, TypeInfo,
|
||||
ValueRef,
|
||||
};
|
||||
use sqlx::mysql::MySqlRow;
|
||||
use sqlx::{Column, ColumnIndex, Database, MySqlPool, Row, TypeInfo, ValueRef};
|
||||
|
||||
use crate::error::{self, Result};
|
||||
use crate::ir::insert_expr::{RowValue, RowValues};
|
||||
@@ -151,33 +148,17 @@ pub struct ValueCount {
|
||||
pub count: i64,
|
||||
}
|
||||
|
||||
pub async fn count_values<'a, DB, E>(e: E, sql: &'a str) -> Result<ValueCount>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as HasArguments<'a>>::Arguments: IntoArguments<'a, DB>,
|
||||
for<'c> E: 'a + Executor<'c, Database = DB>,
|
||||
for<'c> i64: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> String: Encode<'c, DB> + Type<DB>,
|
||||
for<'c> &'c str: ColumnIndex<<DB as Database>::Row>,
|
||||
{
|
||||
Ok(sqlx::query_as::<_, ValueCount>(sql)
|
||||
.fetch_all(e)
|
||||
pub async fn count_values(db: &MySqlPool, sql: &str) -> Result<ValueCount> {
|
||||
sqlx::query_as::<_, ValueCount>(sql)
|
||||
.fetch_one(db)
|
||||
.await
|
||||
.context(error::ExecuteQuerySnafu { sql })?
|
||||
.remove(0))
|
||||
.context(error::ExecuteQuerySnafu { sql })
|
||||
}
|
||||
|
||||
/// Returns all [RowEntry] of the `table_name`.
|
||||
pub async fn fetch_values<'a, DB, E>(e: E, sql: &'a str) -> Result<Vec<<DB as Database>::Row>>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as HasArguments<'a>>::Arguments: IntoArguments<'a, DB>,
|
||||
for<'c> E: 'a + Executor<'c, Database = DB>,
|
||||
for<'c> String: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> String: Encode<'c, DB> + Type<DB>,
|
||||
{
|
||||
pub async fn fetch_values(db: &MySqlPool, sql: &str) -> Result<Vec<MySqlRow>> {
|
||||
sqlx::query(sql)
|
||||
.fetch_all(e)
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.context(error::ExecuteQuerySnafu { sql })
|
||||
}
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use snafu::{ensure, ResultExt};
|
||||
use sqlx::database::HasArguments;
|
||||
use sqlx::{ColumnIndex, Database, Decode, Encode, Executor, IntoArguments, Row, Type};
|
||||
use sqlx::{MySqlPool, Row};
|
||||
|
||||
use crate::error::{self, Result, UnexpectedSnafu};
|
||||
use crate::ir::alter_expr::AlterTableOption;
|
||||
@@ -47,17 +46,9 @@ fn parse_show_create(show_create: &str) -> Result<Vec<AlterTableOption>> {
|
||||
}
|
||||
|
||||
/// Fetches table options from the context
|
||||
pub async fn fetch_table_options<'a, DB, E>(e: E, sql: &'a str) -> Result<Vec<AlterTableOption>>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as HasArguments<'a>>::Arguments: IntoArguments<'a, DB>,
|
||||
for<'c> E: 'a + Executor<'c, Database = DB>,
|
||||
for<'c> String: Decode<'c, DB> + Type<DB>,
|
||||
for<'c> String: Encode<'c, DB> + Type<DB>,
|
||||
usize: ColumnIndex<<DB as Database>::Row>,
|
||||
{
|
||||
pub async fn fetch_table_options(db: &MySqlPool, sql: &str) -> Result<Vec<AlterTableOption>> {
|
||||
let fetched_rows = sqlx::query(sql)
|
||||
.fetch_all(e)
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.context(error::ExecuteQuerySnafu { sql })?;
|
||||
ensure!(
|
||||
|
||||
@@ -64,7 +64,7 @@ session.workspace = true
|
||||
similar-asserts.workspace = true
|
||||
snafu.workspace = true
|
||||
sql.workspace = true
|
||||
sqlx = { version = "0.6", features = [
|
||||
sqlx = { version = "0.8", features = [
|
||||
"runtime-tokio-rustls",
|
||||
"mysql",
|
||||
"postgres",
|
||||
|
||||
Reference in New Issue
Block a user