1
0
mirror of https://github.com/tensorchord/pgvecto.rs.git synced 2025-07-29 08:21:12 +03:00

feat: deny unknown field in options (#184)

* fix: deny unknown options

Signed-off-by: usamoi <usamoi@outlook.com>

* test: deny unknown options

Signed-off-by: usamoi <usamoi@outlook.com>

---------

Signed-off-by: usamoi <usamoi@outlook.com>
This commit is contained in:
Usamoi
2023-12-15 19:02:04 +08:00
committed by GitHub
parent c50912e87d
commit cc1b7d0f17
19 changed files with 38 additions and 10 deletions

View File

@ -15,6 +15,7 @@ use std::sync::Arc;
use validator::Validate; use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum QuantizationOptions { pub enum QuantizationOptions {
Trivial(TrivialQuantizationOptions), Trivial(TrivialQuantizationOptions),

View File

@ -16,6 +16,7 @@ use std::sync::Arc;
use validator::Validate; use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize, Validate)] #[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct ProductQuantizationOptions { pub struct ProductQuantizationOptions {
#[serde(default = "ProductQuantizationOptions::default_sample")] #[serde(default = "ProductQuantizationOptions::default_sample")]
pub sample: u32, pub sample: u32,
@ -40,6 +41,7 @@ impl Default for ProductQuantizationOptions {
#[repr(u16)] #[repr(u16)]
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum ProductQuantizationOptionsRatio { pub enum ProductQuantizationOptionsRatio {
X4 = 1, X4 = 1,

View File

@ -11,6 +11,7 @@ use std::sync::Arc;
use validator::Validate; use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize, Validate)] #[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct ScalarQuantizationOptions {} pub struct ScalarQuantizationOptions {}
impl Default for ScalarQuantizationOptions { impl Default for ScalarQuantizationOptions {

View File

@ -9,6 +9,7 @@ use std::sync::Arc;
use validator::Validate; use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize, Validate)] #[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct TrivialQuantizationOptions {} pub struct TrivialQuantizationOptions {}
impl Default for TrivialQuantizationOptions { impl Default for TrivialQuantizationOptions {

View File

@ -3,6 +3,7 @@ use crate::utils::file_wal::FileWal;
use dashmap::mapref::entry::Entry; use dashmap::mapref::entry::Entry;
use dashmap::DashMap; use dashmap::DashMap;
use parking_lot::Mutex; use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
@ -79,7 +80,7 @@ impl Delete {
} }
} }
#[derive(Debug, serde::Serialize, serde::Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct Log { struct Log {
key: Pointer, key: Pointer,
} }

View File

@ -10,6 +10,7 @@ use std::sync::Arc;
use validator::Validate; use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize, Validate)] #[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct FlatIndexingOptions { pub struct FlatIndexingOptions {
#[serde(default)] #[serde(default)]
#[validate] #[validate]

View File

@ -10,6 +10,7 @@ use std::{path::PathBuf, sync::Arc};
use validator::Validate; use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize, Validate)] #[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct HnswIndexingOptions { pub struct HnswIndexingOptions {
#[serde(default = "HnswIndexingOptions::default_m")] #[serde(default = "HnswIndexingOptions::default_m")]
#[validate(range(min = 4, max = 128))] #[validate(range(min = 4, max = 128))]

View File

@ -11,6 +11,7 @@ use std::sync::Arc;
use validator::Validate; use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize, Validate)] #[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct IvfIndexingOptions { pub struct IvfIndexingOptions {
#[serde(default = "IvfIndexingOptions::default_least_iterations")] #[serde(default = "IvfIndexingOptions::default_least_iterations")]
#[validate(range(min = 1, max = 1_000_000))] #[validate(range(min = 1, max = 1_000_000))]

View File

@ -16,6 +16,7 @@ use std::sync::Arc;
use validator::Validate; use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum IndexingOptions { pub enum IndexingOptions {
Flat(FlatIndexingOptions), Flat(FlatIndexingOptions),

View File

@ -37,6 +37,7 @@ use validator::Validate;
pub struct OutdatedError(#[from] pub Option<GrowingSegmentInsertError>); pub struct OutdatedError(#[from] pub Option<GrowingSegmentInsertError>);
#[derive(Debug, Clone, Serialize, Deserialize, Validate)] #[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct VectorOptions { pub struct VectorOptions {
#[validate(range(min = 1, max = 65535))] #[validate(range(min = 1, max = 65535))]
#[serde(rename = "dimensions")] #[serde(rename = "dimensions")]
@ -48,6 +49,7 @@ pub struct VectorOptions {
} }
#[derive(Debug, Clone, Serialize, Deserialize, Validate)] #[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct IndexOptions { pub struct IndexOptions {
#[validate] #[validate]
pub vector: VectorOptions, pub vector: VectorOptions,
@ -467,7 +469,7 @@ impl<S: G> IndexView<S> {
} }
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
struct IndexStartup { struct IndexStartup {
sealeds: HashSet<Uuid>, sealeds: HashSet<Uuid>,
growings: HashSet<Uuid>, growings: HashSet<Uuid>,

View File

@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
use validator::Validate; use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize, Validate)] #[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct OptimizingOptions { pub struct OptimizingOptions {
#[serde(default = "OptimizingOptions::default_sealing_secs")] #[serde(default = "OptimizingOptions::default_sealing_secs")]
#[validate(range(min = 0, max = 60))] #[validate(range(min = 0, max = 60))]

View File

@ -7,6 +7,7 @@ use crate::prelude::*;
use crate::utils::dir_ops::sync_dir; use crate::utils::dir_ops::sync_dir;
use crate::utils::file_wal::FileWal; use crate::utils::file_wal::FileWal;
use parking_lot::Mutex; use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::path::PathBuf; use std::path::PathBuf;
@ -199,7 +200,7 @@ impl<S: G> Drop for GrowingSegment<S> {
} }
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
struct Log<S: G> { struct Log<S: G> {
vector: Vec<S::Scalar>, vector: Vec<S::Scalar>,
payload: Payload, payload: Payload,

View File

@ -9,6 +9,7 @@ use validator::Validate;
use validator::ValidationError; use validator::ValidationError;
#[derive(Debug, Clone, Serialize, Deserialize, Validate)] #[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
#[validate(schema(function = "Self::validate_0"))] #[validate(schema(function = "Self::validate_0"))]
pub struct SegmentsOptions { pub struct SegmentsOptions {
#[serde(default = "SegmentsOptions::default_max_growing_segment_size")] #[serde(default = "SegmentsOptions::default_max_growing_segment_size")]

View File

@ -87,7 +87,7 @@ pub trait FloatCast: Sized {
} }
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DynamicVector { pub enum DynamicVector {
F32(Vec<F32>), F32(Vec<F32>),
F16(Vec<F16>), F16(Vec<F16>),

View File

@ -1,7 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
use std::ops::{Deref, DerefMut, Index, IndexMut}; use std::ops::{Deref, DerefMut, Index, IndexMut};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone)]
pub struct Vec2<S: G> { pub struct Vec2<S: G> {
dims: u16, dims: u16,
v: Vec<S::Scalar>, v: Vec<S::Scalar>,

View File

@ -10,6 +10,7 @@ use crate::utils::dir_ops::sync_dir;
use crate::utils::file_atomic::FileAtomic; use crate::utils::file_atomic::FileAtomic;
use arc_swap::ArcSwap; use arc_swap::ArcSwap;
use parking_lot::Mutex; use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use serde_with::DisplayFromStr; use serde_with::DisplayFromStr;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::PathBuf; use std::path::PathBuf;
@ -172,7 +173,7 @@ impl WorkerProtect {
} }
#[serde_with::serde_as] #[serde_with::serde_as]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
struct WorkerStartup { struct WorkerStartup {
#[serde_as(as = "HashMap<DisplayFromStr, _>")] #[serde_as(as = "HashMap<DisplayFromStr, _>")]
indexes: HashMap<Id, IndexOptions>, indexes: HashMap<Id, IndexOptions>,

View File

@ -1,5 +1,5 @@
use crate::datatype::typmod::Typmod; use crate::datatype::typmod::Typmod;
use serde::{Deserialize, Serialize}; use serde::Deserialize;
use service::index::indexing::IndexingOptions; use service::index::indexing::IndexingOptions;
use service::index::optimizing::OptimizingOptions; use service::index::optimizing::OptimizingOptions;
use service::index::segments::SegmentsOptions; use service::index::segments::SegmentsOptions;
@ -118,7 +118,8 @@ unsafe fn get_parsed_from_varlena(helper: *const pgrx::pg_sys::varlena) -> Parse
toml::from_str::<Parsed>(cstr.to_str().unwrap()).unwrap() toml::from_str::<Parsed>(cstr.to_str().unwrap()).unwrap()
} }
#[derive(Debug, Clone, Serialize, Deserialize, Default)] #[derive(Debug, Clone, Deserialize, Default)]
#[serde(deny_unknown_fields)]
struct Parsed { struct Parsed {
#[serde(default)] #[serde(default)]
segment: SegmentsOptions, segment: SegmentsOptions,

View File

@ -1,5 +1,4 @@
use serde::Deserialize; use serde::{Deserialize, Serialize};
use serde::Serialize;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub enum CreatePacket { pub enum CreatePacket {

View File

@ -0,0 +1,12 @@
statement ok
DROP TABLE IF EXISTS t;
statement ok
CREATE TABLE t (val vector(3));
statement ok
INSERT INTO t (val) SELECT ARRAY[random(), random(), random()]::real[] FROM generate_series(1, 1000);
statement error unknown
CREATE INDEX ON t USING vectors (val vector_l2_ops)
WITH (options = "unknown_field = 1");